Commit d40e339a authored by Brickner_cp's avatar Brickner_cp

Improved UInt48.

Fixed a bug when marshaling empty strings.
Added minimum and maximum timestamps definitions.
New feature: Dump packets to file without a device.
Added a complex test that compares wireshark parsing with Pcap.Net parsing.
Added the possibility to get the IpV4 version (not assuming the value is 4).
CountTimeStamps added to timestamp options.
parent 68437e53
...@@ -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.Test.dll" pdbFile="C:\TFS\tfs06.codeplex.com\PcapDotNet\PcapDotNet\bin\Debug\PcapDotNet.Core.Test.pdb" instrumentInPlace="true" />
</Regular> </Regular>
</CodeCoverage> </CodeCoverage>
<TestTypeSpecific> <TestTypeSpecific>
......
...@@ -36,4 +36,4 @@ using System.Runtime.InteropServices; ...@@ -36,4 +36,4 @@ using System.Runtime.InteropServices;
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: CLSCompliant(true)] [assembly: CLSCompliant(false)]
\ No newline at end of file \ No newline at end of file
using System;
using System.Globalization; using System.Globalization;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
...@@ -19,6 +20,34 @@ namespace PcapDotNet.Base ...@@ -19,6 +20,34 @@ namespace PcapDotNet.Base
/// </summary> /// </summary>
public static readonly UInt48 MaxValue = (UInt48)0x0000FFFFFFFFFFFF; public static readonly UInt48 MaxValue = (UInt48)0x0000FFFFFFFFFFFF;
/// <summary>
/// Converts the string representation of a number in a specified style to its 48-bit unsigned integer equivalent.
/// </summary>
/// <param name="value">A string representing the number to convert.</param>
/// <param name="style">
/// A bitwise combination of NumberStyles values that indicates the permitted format of s.
/// A typical value to specify is NumberStyles.Integer.
/// </param>
/// <returns>A 48-bit unsigned integer equivalent to the number specified in s.</returns>
public static UInt48 Parse(string value, NumberStyles style, IFormatProvider provider)
{
ulong parsedValue = ulong.Parse(value, style, provider);
if (parsedValue > MaxValue)
throw new FormatException("parsed value " + parsedValue + " is larger than max value " + MaxValue);
return (UInt48)parsedValue;
}
/// <summary>
/// Converts a 32 bit unsigned integer to a 48 bit unsigned integer by taking all the 32 bits.
/// </summary>
/// <param name="value">The 32 bit value to convert.</param>
/// <returns>The 48 bit value created by taking all the 32 bits of the 32bit value.</returns>
public static implicit operator UInt48(uint value)
{
return new UInt48(value);
}
/// <summary> /// <summary>
/// Converts a 64 bit signed integer to a 48 bit unsigned integer by taking the 48 least significant bits. /// Converts a 64 bit signed integer to a 48 bit unsigned integer by taking the 48 least significant bits.
/// </summary> /// </summary>
...@@ -29,6 +58,16 @@ namespace PcapDotNet.Base ...@@ -29,6 +58,16 @@ namespace PcapDotNet.Base
return new UInt48(value); return new UInt48(value);
} }
/// <summary>
/// Converts a 64 bit unsigned integer to a 48 bit unsigned integer by taking the 48 least significant bits.
/// </summary>
/// <param name="value">The 64 bit value to convert.</param>
/// <returns>The 48 bit value created by taking the 48 least significant bits of the 64 bit value.</returns>
public static explicit operator UInt48(ulong value)
{
return new UInt48((long)value);
}
/// <summary> /// <summary>
/// Converts the 48 bits unsigned integer to a 64 bits signed integer. /// Converts the 48 bits unsigned integer to a 64 bits signed integer.
/// </summary> /// </summary>
...@@ -39,6 +78,26 @@ namespace PcapDotNet.Base ...@@ -39,6 +78,26 @@ namespace PcapDotNet.Base
return value.ToLong(); return value.ToLong();
} }
/// <summary>
/// Converts the 48 bits unsigned integer to a 64 bits unsigned integer.
/// </summary>
/// <param name="value">The 48 bit value to convert.</param>
/// <returns>The 64 bit value converted from the 48 bit value.</returns>
public static implicit operator ulong(UInt48 value)
{
return (ulong)value.ToLong();
}
/// <summary>
/// Converts the 48 bits unsigned integer to an 8 bits unsigned integer.
/// </summary>
/// <param name="value">The 48 bit value to convert.</param>
/// <returns>The 8 bit value converted from the 48 bit value.</returns>
public static explicit operator byte(UInt48 value)
{
return (byte)value.ToByte();
}
/// <summary> /// <summary>
/// Returns true iff the two values represent the same value. /// Returns true iff the two values represent the same value.
/// </summary> /// </summary>
...@@ -120,7 +179,13 @@ namespace PcapDotNet.Base ...@@ -120,7 +179,13 @@ namespace PcapDotNet.Base
return (((long)_mostSignificant) << 32) + _leastSignificant; return (((long)_mostSignificant) << 32) + _leastSignificant;
} }
private byte ToByte()
{
return (byte)_leastSignificant;
}
private readonly uint _leastSignificant; private readonly uint _leastSignificant;
private readonly ushort _mostSignificant; private readonly ushort _mostSignificant;
} }
} }
\ No newline at end of file
...@@ -75,8 +75,8 @@ namespace PcapDotNet.Core.Test ...@@ -75,8 +75,8 @@ namespace PcapDotNet.Core.Test
const string DestinationMac = "77:88:99:AA:BB:CC"; const string DestinationMac = "77:88:99:AA:BB:CC";
Random random = new Random(); Random random = new Random();
Packet expectedPacket = random.NextEthernet(1000, SourceMac, DestinationMac); Packet expectedPacket = random.NextEthernetPacket(1000, SourceMac, DestinationMac);
Packet unexpectedPacket = random.NextEthernet(1000, DestinationMac, SourceMac); Packet unexpectedPacket = random.NextEthernetPacket(1000, DestinationMac, SourceMac);
using (BerkeleyPacketFilter filter = new BerkeleyPacketFilter("ether src " + SourceMac + " and ether dst " + DestinationMac, 1000, DataLinkKind.Ethernet)) using (BerkeleyPacketFilter filter = new BerkeleyPacketFilter("ether src " + SourceMac + " and ether dst " + DestinationMac, 1000, DataLinkKind.Ethernet))
{ {
...@@ -94,8 +94,8 @@ namespace PcapDotNet.Core.Test ...@@ -94,8 +94,8 @@ namespace PcapDotNet.Core.Test
const string DestinationMac = "77:88:99:AA:BB:CC"; const string DestinationMac = "77:88:99:AA:BB:CC";
Random random = new Random(); Random random = new Random();
Packet expectedPacket = random.NextEthernet(1000, SourceMac, DestinationMac); Packet expectedPacket = random.NextEthernetPacket(1000, SourceMac, DestinationMac);
Packet unexpectedPacket = random.NextEthernet(1000, DestinationMac, SourceMac); Packet unexpectedPacket = random.NextEthernetPacket(1000, DestinationMac, SourceMac);
using (PacketCommunicator communicator = LivePacketDeviceTests.OpenLiveDevice()) using (PacketCommunicator communicator = LivePacketDeviceTests.OpenLiveDevice())
{ {
...@@ -117,16 +117,16 @@ namespace PcapDotNet.Core.Test ...@@ -117,16 +117,16 @@ namespace PcapDotNet.Core.Test
using (BerkeleyPacketFilter filter = new BerkeleyPacketFilter("ether src " + SourceMac + " and ether dst " + DestinationMac, snapshotLength, DataLinkKind.Ethernet)) using (BerkeleyPacketFilter filter = new BerkeleyPacketFilter("ether src " + SourceMac + " and ether dst " + DestinationMac, snapshotLength, DataLinkKind.Ethernet))
{ {
Assert.IsTrue(filter.Test(random.NextEthernet(snapshotLength / 2, SourceMac, DestinationMac))); Assert.IsTrue(filter.Test(random.NextEthernetPacket(snapshotLength / 2, SourceMac, DestinationMac)));
Assert.IsTrue(filter.Test(random.NextEthernet(snapshotLength - 1, SourceMac, DestinationMac))); Assert.IsTrue(filter.Test(random.NextEthernetPacket(snapshotLength - 1, SourceMac, DestinationMac)));
Assert.IsTrue(filter.Test(random.NextEthernet(snapshotLength, SourceMac, DestinationMac))); Assert.IsTrue(filter.Test(random.NextEthernetPacket(snapshotLength, SourceMac, DestinationMac)));
Assert.IsTrue(filter.Test(random.NextEthernet(snapshotLength + 1, SourceMac, DestinationMac))); Assert.IsTrue(filter.Test(random.NextEthernetPacket(snapshotLength + 1, SourceMac, DestinationMac)));
Assert.IsTrue(filter.Test(random.NextEthernet(snapshotLength * 2, SourceMac, DestinationMac))); Assert.IsTrue(filter.Test(random.NextEthernetPacket(snapshotLength * 2, SourceMac, DestinationMac)));
Assert.IsFalse(filter.Test(random.NextEthernet(snapshotLength / 2, DestinationMac, SourceMac))); Assert.IsFalse(filter.Test(random.NextEthernetPacket(snapshotLength / 2, DestinationMac, SourceMac)));
int actualSnapshotLength; int actualSnapshotLength;
Assert.IsTrue(filter.Test(out actualSnapshotLength, random.NextEthernet(snapshotLength / 2, SourceMac, DestinationMac))); Assert.IsTrue(filter.Test(out actualSnapshotLength, random.NextEthernetPacket(snapshotLength / 2, SourceMac, DestinationMac)));
Assert.AreEqual(snapshotLength, actualSnapshotLength); Assert.AreEqual(snapshotLength, actualSnapshotLength);
} }
} }
......
using System; using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets;
using PcapDotNet.Packets.Ethernet; using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.TestUtils; using PcapDotNet.Packets.TestUtils;
using PcapDotNet.TestUtils; using PcapDotNet.TestUtils;
...@@ -65,11 +68,9 @@ namespace PcapDotNet.Core.Test ...@@ -65,11 +68,9 @@ namespace PcapDotNet.Core.Test
{ {
MacAddress ethernetSource = new MacAddress("00:01:02:03:04:05"); MacAddress ethernetSource = new MacAddress("00:01:02:03:04:05");
MacAddress ethernetDestination = new MacAddress("A0:A1:A2:A3:A4:A5"); MacAddress ethernetDestination = new MacAddress("A0:A1:A2:A3:A4:A5");
const EthernetType ethernetType = EthernetType.IpV4;
Random random = new Random(); Random random = new Random();
/*
using (PacketCommunicator communicator = LivePacketDeviceTests.OpenLiveDevice()) using (PacketCommunicator communicator = LivePacketDeviceTests.OpenLiveDevice())
{ {
using (PacketDumpFile dumpFile = communicator.OpenDump(@"c:\wow.pcap")) using (PacketDumpFile dumpFile = communicator.OpenDump(@"c:\wow.pcap"))
...@@ -80,7 +81,7 @@ namespace PcapDotNet.Core.Test ...@@ -80,7 +81,7 @@ namespace PcapDotNet.Core.Test
ushort ipV4Identification = random.NextUShort(); ushort ipV4Identification = random.NextUShort();
byte ipV4Ttl = random.NextByte(); byte ipV4Ttl = random.NextByte();
IpV4FragmentationOptions ipV4FragmentationFlags = random.NextEnum<IpV4FragmentationOptions>(); IpV4FragmentationOptions ipV4FragmentationFlags = random.NextEnum<IpV4FragmentationOptions>();
ushort ipV4FragmentationOffset = random.NextUShort(); ushort ipV4FragmentationOffset = (ushort)(random.NextUShort() / 8 * 8);
IpV4Fragmentation ipV4Fragmentation = new IpV4Fragmentation(ipV4FragmentationFlags, ipV4FragmentationOffset); IpV4Fragmentation ipV4Fragmentation = new IpV4Fragmentation(ipV4FragmentationFlags, ipV4FragmentationOffset);
IpV4Protocol ipV4Protocol = random.NextEnum<IpV4Protocol>(); IpV4Protocol ipV4Protocol = random.NextEnum<IpV4Protocol>();
IpV4Address ipV4Source = new IpV4Address(random.NextUInt()); IpV4Address ipV4Source = new IpV4Address(random.NextUInt());
...@@ -92,7 +93,7 @@ namespace PcapDotNet.Core.Test ...@@ -92,7 +93,7 @@ namespace PcapDotNet.Core.Test
Datagram ipV4Payload = new Datagram(ipV4PayloadBuffer); Datagram ipV4Payload = new Datagram(ipV4PayloadBuffer);
Packet packet = PacketBuilder.EthernetIpV4(DateTime.Now, Packet packet = PacketBuilder.EthernetIpV4(DateTime.Now,
ethernetSource, ethernetDestination, ethernetType, ethernetSource, ethernetDestination,
ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl, ipV4Protocol, ipV4TypeOfService, ipV4Identification, ipV4Fragmentation, ipV4Ttl, ipV4Protocol,
ipV4Source, ipV4Destination, ipV4Options, ipV4Source, ipV4Destination, ipV4Options,
ipV4Payload); ipV4Payload);
...@@ -102,7 +103,79 @@ namespace PcapDotNet.Core.Test ...@@ -102,7 +103,79 @@ namespace PcapDotNet.Core.Test
} }
} }
} }
*/ }
}
/// <summary>
/// Summary description for PacketDumpFileTests
/// </summary>
[TestClass]
public class PacketDumpFileTests
{
public PacketDumpFileTests()
{
//
// TODO: Add constructor logic here
//
}
private TestContext testContextInstance;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
#region Additional test attributes
//
// You can use the following additional attributes as you write your tests:
//
// Use ClassInitialize to run code before running the first test in the class
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext testContext) { }
//
// Use ClassCleanup to run code after all tests in a class have run
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// Use TestInitialize to run code before running each test
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// Use TestCleanup to run code after each test has run
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion
[TestMethod]
public void DumpWithoutDeviceTest()
{
string filename = Path.GetTempPath() + @"dump.pcap";
Packet expectedPacket = PacketBuilder.Ethernet(DateTime.Now, new MacAddress(1), new MacAddress(2), EthernetType.QInQ,
new Datagram(new byte[] {1, 2, 3}));
PacketDumpFile.Dump(filename, new PcapDataLink(DataLinkKind.Ethernet), PacketDevice.DefaultSnapshotLength,
new[] {expectedPacket});
using (PacketCommunicator communicator = new OfflinePacketDevice(filename).Open())
{
Packet actualPacket;
PacketCommunicatorReceiveResult result = communicator.ReceivePacket(out actualPacket);
Assert.AreEqual(PacketCommunicatorReceiveResult.Ok, result);
Assert.AreEqual(expectedPacket, actualPacket);
}
} }
} }
} }
\ No newline at end of file
...@@ -83,7 +83,7 @@ namespace PcapDotNet.Core.Test ...@@ -83,7 +83,7 @@ namespace PcapDotNet.Core.Test
Assert.AreEqual<uint>(0, communicator.TotalStatistics.PacketsCaptured); Assert.AreEqual<uint>(0, communicator.TotalStatistics.PacketsCaptured);
MoreAssert.IsInRange(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1.02), finishedWaiting - startWaiting); MoreAssert.IsInRange(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1.02), finishedWaiting - startWaiting);
Packet sentPacket = _random.NextEthernet(24, SourceMac, DestinationMac); Packet sentPacket = _random.NextEthernetPacket(24, SourceMac, DestinationMac);
DateTime startSendingTime = DateTime.Now; DateTime startSendingTime = DateTime.Now;
...@@ -159,7 +159,7 @@ namespace PcapDotNet.Core.Test ...@@ -159,7 +159,7 @@ namespace PcapDotNet.Core.Test
{ {
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
Packet sentPacket = _random.NextEthernet(100, SourceMac, DestinationMac); Packet sentPacket = _random.NextEthernetPacket(100, SourceMac, DestinationMac);
for (int i = 0; i != NumPackets; ++i) for (int i = 0; i != NumPackets; ++i)
communicator.SendPacket(sentPacket); communicator.SendPacket(sentPacket);
...@@ -184,7 +184,7 @@ namespace PcapDotNet.Core.Test ...@@ -184,7 +184,7 @@ namespace PcapDotNet.Core.Test
{ {
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
Packet sentPacket = _random.NextEthernet(100, SourceMac, DestinationMac); Packet sentPacket = _random.NextEthernetPacket(100, SourceMac, DestinationMac);
for (int i = 0; i != NumPackets; ++i) for (int i = 0; i != NumPackets; ++i)
communicator.SendPacket(sentPacket); communicator.SendPacket(sentPacket);
...@@ -234,7 +234,7 @@ namespace PcapDotNet.Core.Test ...@@ -234,7 +234,7 @@ namespace PcapDotNet.Core.Test
communicator.Mode = PacketCommunicatorMode.Statistics; communicator.Mode = PacketCommunicatorMode.Statistics;
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
Packet sentPacket = _random.NextEthernet(PacketSize, SourceMac, DestinationMac); Packet sentPacket = _random.NextEthernetPacket(PacketSize, SourceMac, DestinationMac);
PacketSampleStatistics statistics; PacketSampleStatistics statistics;
PacketCommunicatorReceiveResult result = communicator.ReceiveStatistics(out statistics); PacketCommunicatorReceiveResult result = communicator.ReceiveStatistics(out statistics);
...@@ -341,7 +341,7 @@ namespace PcapDotNet.Core.Test ...@@ -341,7 +341,7 @@ namespace PcapDotNet.Core.Test
{ {
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
communicator.SetKernelBufferSize(50); communicator.SetKernelBufferSize(50);
Packet packet = _random.NextEthernet(100, SourceMac, DestinationMac); Packet packet = _random.NextEthernetPacket(100, SourceMac, DestinationMac);
communicator.SendPacket(packet); communicator.SendPacket(packet);
communicator.ReceivePacket(out packet); communicator.ReceivePacket(out packet);
} }
...@@ -358,7 +358,7 @@ namespace PcapDotNet.Core.Test ...@@ -358,7 +358,7 @@ namespace PcapDotNet.Core.Test
{ {
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
communicator.SetKernelBufferSize(50); communicator.SetKernelBufferSize(50);
Packet packet = _random.NextEthernet(100, SourceMac, DestinationMac); Packet packet = _random.NextEthernetPacket(100, SourceMac, DestinationMac);
communicator.SendPacket(packet); communicator.SendPacket(packet);
int numPacketsGot; int numPacketsGot;
communicator.ReceiveSomePackets(out numPacketsGot, 1, delegate { }); communicator.ReceiveSomePackets(out numPacketsGot, 1, delegate { });
...@@ -376,7 +376,7 @@ namespace PcapDotNet.Core.Test ...@@ -376,7 +376,7 @@ namespace PcapDotNet.Core.Test
{ {
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
communicator.SetKernelBufferSize(50); communicator.SetKernelBufferSize(50);
Packet packet = _random.NextEthernet(100, SourceMac, DestinationMac); Packet packet = _random.NextEthernetPacket(100, SourceMac, DestinationMac);
communicator.SendPacket(packet); communicator.SendPacket(packet);
Exception exception = null; Exception exception = null;
Thread thread = new Thread(delegate() Thread thread = new Thread(delegate()
...@@ -434,7 +434,7 @@ namespace PcapDotNet.Core.Test ...@@ -434,7 +434,7 @@ namespace PcapDotNet.Core.Test
{ {
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
communicator.SetKernelMinimumBytesToCopy(1024 * 1024); communicator.SetKernelMinimumBytesToCopy(1024 * 1024);
Packet expectedPacket = _random.NextEthernet(100, SourceMac, DestinationMac); Packet expectedPacket = _random.NextEthernetPacket(100, SourceMac, DestinationMac);
for (int i = 0; i != 5; ++i) for (int i = 0; i != 5; ++i)
{ {
communicator.SendPacket(expectedPacket); communicator.SendPacket(expectedPacket);
...@@ -459,7 +459,7 @@ namespace PcapDotNet.Core.Test ...@@ -459,7 +459,7 @@ namespace PcapDotNet.Core.Test
{ {
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
communicator.SetKernelMinimumBytesToCopy(1); communicator.SetKernelMinimumBytesToCopy(1);
Packet expectedPacket = _random.NextEthernet(100, SourceMac, DestinationMac); Packet expectedPacket = _random.NextEthernetPacket(100, SourceMac, DestinationMac);
for (int i = 0; i != 100; ++i) for (int i = 0; i != 100; ++i)
{ {
communicator.SendPacket(expectedPacket); communicator.SendPacket(expectedPacket);
...@@ -486,7 +486,7 @@ namespace PcapDotNet.Core.Test ...@@ -486,7 +486,7 @@ namespace PcapDotNet.Core.Test
communicator.SetSamplingMethod(new SamplingMethodOneEveryCount(5)); communicator.SetSamplingMethod(new SamplingMethodOneEveryCount(5));
for (int i = 0; i != 20; ++i) for (int i = 0; i != 20; ++i)
{ {
Packet expectedPacket = _random.NextEthernet(60 * (i + 1), SourceMac, DestinationMac); Packet expectedPacket = _random.NextEthernetPacket(60 * (i + 1), SourceMac, DestinationMac);
communicator.SendPacket(expectedPacket); communicator.SendPacket(expectedPacket);
} }
...@@ -514,12 +514,12 @@ namespace PcapDotNet.Core.Test ...@@ -514,12 +514,12 @@ namespace PcapDotNet.Core.Test
{ {
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
communicator.SetSamplingMethod(new SamplingMethodFirstAfterInterval(TimeSpan.FromSeconds(1))); communicator.SetSamplingMethod(new SamplingMethodFirstAfterInterval(TimeSpan.FromSeconds(1)));
Packet expectedPacket = _random.NextEthernet(60, SourceMac, DestinationMac); Packet expectedPacket = _random.NextEthernetPacket(60, SourceMac, DestinationMac);
communicator.SendPacket(expectedPacket); communicator.SendPacket(expectedPacket);
Thread.Sleep(TimeSpan.FromSeconds(0.75)); Thread.Sleep(TimeSpan.FromSeconds(0.75));
for (int i = 0; i != 10; ++i) for (int i = 0; i != 10; ++i)
{ {
expectedPacket = _random.NextEthernet(60 * (i + 2), SourceMac, DestinationMac); expectedPacket = _random.NextEthernetPacket(60 * (i + 2), SourceMac, DestinationMac);
communicator.SendPacket(expectedPacket); communicator.SendPacket(expectedPacket);
Thread.Sleep(TimeSpan.FromSeconds(0.5)); Thread.Sleep(TimeSpan.FromSeconds(0.5));
} }
...@@ -587,7 +587,7 @@ namespace PcapDotNet.Core.Test ...@@ -587,7 +587,7 @@ namespace PcapDotNet.Core.Test
communicator.SetFilter("ether src " + sourceMac + " and ether dst " + destinationMac); communicator.SetFilter("ether src " + sourceMac + " and ether dst " + destinationMac);
Packet sentPacket = _random.NextEthernet(packetSize, sourceMac, destinationMac); Packet sentPacket = _random.NextEthernetPacket(packetSize, sourceMac, destinationMac);
PacketCommunicatorReceiveResult result = PacketCommunicatorReceiveResult.None; PacketCommunicatorReceiveResult result = PacketCommunicatorReceiveResult.None;
int numStatisticsGot = 0; int numStatisticsGot = 0;
...@@ -637,7 +637,7 @@ namespace PcapDotNet.Core.Test ...@@ -637,7 +637,7 @@ namespace PcapDotNet.Core.Test
const string SourceMac = "11:22:33:44:55:66"; const string SourceMac = "11:22:33:44:55:66";
const string DestinationMac = "77:88:99:AA:BB:CC"; const string DestinationMac = "77:88:99:AA:BB:CC";
Packet packetToSend = _random.NextEthernet(packetSize, SourceMac, DestinationMac); Packet packetToSend = _random.NextEthernetPacket(packetSize, SourceMac, DestinationMac);
using (PacketCommunicator communicator = OpenLiveDevice()) using (PacketCommunicator communicator = OpenLiveDevice())
{ {
...@@ -681,7 +681,7 @@ namespace PcapDotNet.Core.Test ...@@ -681,7 +681,7 @@ namespace PcapDotNet.Core.Test
{ {
communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac); communicator.SetFilter("ether src " + SourceMac + " and ether dst " + DestinationMac);
Packet sentPacket = _random.NextEthernet(packetSize, SourceMac, DestinationMac); Packet sentPacket = _random.NextEthernetPacket(packetSize, SourceMac, DestinationMac);
PacketCommunicatorReceiveResult result = PacketCommunicatorReceiveResult.None; PacketCommunicatorReceiveResult result = PacketCommunicatorReceiveResult.None;
......
using System;
using System.Collections.Generic;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Core.Test
{
internal static class MoreIpV4Option
{
public static string GetWiresharkString(this IpV4Option option)
{
switch (option.OptionType)
{
case IpV4OptionType.EndOfOptionList:
return "EOL";
case IpV4OptionType.NoOperation:
return "NOP";
case IpV4OptionType.Security:
return "Security:";
case IpV4OptionType.LooseSourceRouting:
return "Loose source route (" + option.Length + " bytes)";
case IpV4OptionType.StrictSourceRouting:
return "Strict source route (" + option.Length + " bytes)";
case IpV4OptionType.RecordRoute:
return "Record route (" + option.Length + " bytes)";
case IpV4OptionType.StreamIdentifier:
return "Stream identifier: " + ((IpV4OptionStreamIdentifier)option).Identifier;
case IpV4OptionType.InternetTimestamp:
return "Time stamp" + (option.Length < 5 ? " (with option length = " + option.Length + " bytes; should be >= 5)" : ":");
default:
throw new InvalidOperationException("Illegal option type " + option.OptionType);
}
}
public static IEnumerable<string> GetWiresharkSubfieldStrings(this IpV4Option option)
{
switch (option.OptionType)
{
case IpV4OptionType.EndOfOptionList:
case IpV4OptionType.NoOperation:
case IpV4OptionType.StreamIdentifier:
break;
case IpV4OptionType.Security:
IpV4OptionSecurity securityOption = (IpV4OptionSecurity)option;
switch (securityOption.Level)
{
case IpV4OptionSecurityLevel.EncryptedForTransmissionOnly:
yield return "Security: EFTO";
break;
case IpV4OptionSecurityLevel.Mmmm:
yield return "Security: " + securityOption.Level.ToString().ToUpper();
break;
case IpV4OptionSecurityLevel.TopSecret:
yield return "Security: Top secret";
break;
case IpV4OptionSecurityLevel.Prog:
yield return "Security: Unknown (0x" + ((ushort)securityOption.Level).ToString("x4") + ")";
break;
default:
yield return "Security: " + securityOption.Level;
break;
}
yield return "Compartments: " + securityOption.Compartments;
yield return "Handling restrictions: ";
yield return "Transmission control code: ";
break;
case IpV4OptionType.LooseSourceRouting:
case IpV4OptionType.StrictSourceRouting:
case IpV4OptionType.RecordRoute:
IpV4OptionRoute routeOption = (IpV4OptionRoute)option;
yield return "Pointer: " + (routeOption.PointedAddressIndex * 4 + 4);
for (int i = 0; i != routeOption.Route.Count; ++i)
yield return routeOption.Route[i] + (routeOption.PointedAddressIndex == i ? " <- (current)" : string.Empty);
break;
case IpV4OptionType.InternetTimestamp:
IpV4OptionTimestamp timestampOption = (IpV4OptionTimestamp)option;
if (timestampOption.CountTimestamps == 0)
break;
yield return "Pointer: " + (timestampOption.PointedIndex * 4 + 5);
yield return "Overflow: " + timestampOption.Overflow;
switch (timestampOption.TimestampType)
{
case IpV4OptionTimestampType.TimestampOnly:
yield return "Flag: Time stamps only";
IpV4OptionTimestampOnly timestampOnlyOption = (IpV4OptionTimestampOnly)option;
foreach (IpV4OptionTimeOfDay timeOfDay in timestampOnlyOption.Timestamps)
yield return "Time stamp = " + timeOfDay.MillisecondsSinceMidnightUniversalTime;
break;
case IpV4OptionTimestampType.AddressAndTimestamp:
yield return "Flag: Time stamp and address";
IpV4OptionTimestampAndAddress timestampAndAddressOption = (IpV4OptionTimestampAndAddress)option;
foreach (IpV4OptionTimedAddress timedAddress in timestampAndAddressOption.TimedRoute)
{
yield return "Address = " + timedAddress.Address + ", " +
"time stamp = " + timedAddress.TimeOfDay.MillisecondsSinceMidnightUniversalTime;
}
break;
case IpV4OptionTimestampType.AddressPrespecified:
yield return "Flag: Time stamps for prespecified addresses";
IpV4OptionTimestampAndAddress timestampPrespecifiedOption = (IpV4OptionTimestampAndAddress)option;
foreach (IpV4OptionTimedAddress timedAddress in timestampPrespecifiedOption.TimedRoute)
{
yield return "Time stamp = " + timedAddress.Address.ToValue();
yield return "Time stamp = " + timedAddress.TimeOfDay.MillisecondsSinceMidnightUniversalTime;
}
break;
default:
throw new InvalidOperationException("Illegal timestamp type " + timestampOption.TimestampType);
}
break;
default:
throw new InvalidOperationException("Illegal option type " + option.OptionType);
}
}
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace PcapDotNet.Core.Test
{
internal static class MoreXElement
{
public static IEnumerable<XElement> Fields(this XElement element)
{
return element.Elements("field");
}
public static string Name(this XElement element)
{
return element.Attribute("name").Value;
}
public static string Show(this XElement element)
{
return element.Attribute("show").Value;
}
public static string Value(this XElement element)
{
return element.Attribute("value").Value;
}
public static void AssertShow(this XElement element, string value)
{
Assert.AreEqual(element.Show(), value);
}
public static void AssertShowDecimal(this XElement element, bool value)
{
element.AssertShowDecimal(value ? 1 : 0);
}
public static void AssertShowDecimal(this XElement element, byte value)
{
Assert.AreEqual(element.Show(), value.ToString());
}
public static void AssertShowDecimal(this XElement element, short value)
{
Assert.AreEqual(element.Show(), value.ToString());
}
public static void AssertShowDecimal(this XElement element, ushort value)
{
Assert.AreEqual(element.Show(), value.ToString());
}
public static void AssertShowDecimal(this XElement element, int value)
{
Assert.AreEqual(element.Show(), value.ToString(), element.Name());
}
public static void AssertShowDecimal(this XElement element, uint value)
{
Assert.AreEqual(element.Show(), value.ToString());
}
public static void AssertShowDecimal(this XElement element, long value)
{
Assert.AreEqual(element.Show(), value.ToString());
}
public static void AssertShowDecimal(this XElement element, ulong value)
{
Assert.AreEqual(element.Show(), value.ToString());
}
public static void AssertShowHex(this XElement element, byte value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(byte)));
}
public static void AssertShowHex(this XElement element, short value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(ushort)));
}
public static void AssertShowHex(this XElement element, ushort value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(ushort)));
}
public static void AssertShowHex(this XElement element, int value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(int)));
}
public static void AssertShowHex(this XElement element, uint value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(uint)));
}
public static void AssertShowHex(this XElement element, long value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(long)));
}
public static void AssertShowHex(this XElement element, ulong value)
{
Assert.AreEqual(element.Show(), "0x" + value.ToString("x" + 2 * sizeof(ulong)));
}
}
}
\ No newline at end of file
...@@ -68,7 +68,7 @@ namespace PcapDotNet.Core.Test ...@@ -68,7 +68,7 @@ namespace PcapDotNet.Core.Test
const string DestinationMac = "77:88:99:AA:BB:CC"; const string DestinationMac = "77:88:99:AA:BB:CC";
const int NumPackets = 10; const int NumPackets = 10;
Packet expectedPacket = _random.NextEthernet(100, SourceMac, DestinationMac); Packet expectedPacket = _random.NextEthernetPacket(100, SourceMac, DestinationMac);
using (PacketCommunicator communicator = OpenOfflineDevice(NumPackets, expectedPacket)) using (PacketCommunicator communicator = OpenOfflineDevice(NumPackets, expectedPacket))
{ {
...@@ -177,7 +177,7 @@ namespace PcapDotNet.Core.Test ...@@ -177,7 +177,7 @@ namespace PcapDotNet.Core.Test
{ {
using (PacketCommunicator communicator = OpenOfflineDevice()) using (PacketCommunicator communicator = OpenOfflineDevice())
{ {
communicator.SendPacket(_random.NextEthernet(100)); communicator.SendPacket(_random.NextEthernetPacket(100));
} }
} }
...@@ -204,7 +204,7 @@ namespace PcapDotNet.Core.Test ...@@ -204,7 +204,7 @@ namespace PcapDotNet.Core.Test
[TestMethod] [TestMethod]
public void SetSamplingMethodOneEveryNTest() public void SetSamplingMethodOneEveryNTest()
{ {
Packet expectedPacket = _random.NextEthernet(100); Packet expectedPacket = _random.NextEthernetPacket(100);
using (PacketCommunicator communicator = OpenOfflineDevice(101, expectedPacket)) using (PacketCommunicator communicator = OpenOfflineDevice(101, expectedPacket))
{ {
communicator.SetSamplingMethod(new SamplingMethodOneEveryCount(10)); communicator.SetSamplingMethod(new SamplingMethodOneEveryCount(10));
...@@ -227,7 +227,7 @@ namespace PcapDotNet.Core.Test ...@@ -227,7 +227,7 @@ namespace PcapDotNet.Core.Test
{ {
const int NumPackets = 10; const int NumPackets = 10;
Packet expectedPacket = _random.NextEthernet(100); Packet expectedPacket = _random.NextEthernetPacket(100);
using (PacketCommunicator communicator = OpenOfflineDevice(NumPackets, expectedPacket, TimeSpan.FromSeconds(1))) using (PacketCommunicator communicator = OpenOfflineDevice(NumPackets, expectedPacket, TimeSpan.FromSeconds(1)))
{ {
communicator.SetSamplingMethod(new SamplingMethodFirstAfterInterval(TimeSpan.FromSeconds(2))); communicator.SetSamplingMethod(new SamplingMethodFirstAfterInterval(TimeSpan.FromSeconds(2)));
...@@ -252,7 +252,7 @@ namespace PcapDotNet.Core.Test ...@@ -252,7 +252,7 @@ namespace PcapDotNet.Core.Test
[ExpectedException(typeof(InvalidOperationException))] [ExpectedException(typeof(InvalidOperationException))]
public void DumpToBadFileTest() public void DumpToBadFileTest()
{ {
OpenOfflineDevice(10, _random.NextEthernet(100), TimeSpan.Zero, "??"); OpenOfflineDevice(10, _random.NextEthernetPacket(100), TimeSpan.Zero, "??");
} }
private static void TestGetSomePackets(int numPacketsToSend, int numPacketsToGet, int numPacketsToBreakLoop, private static void TestGetSomePackets(int numPacketsToSend, int numPacketsToGet, int numPacketsToBreakLoop,
...@@ -265,7 +265,7 @@ namespace PcapDotNet.Core.Test ...@@ -265,7 +265,7 @@ namespace PcapDotNet.Core.Test
const string SourceMac = "11:22:33:44:55:66"; const string SourceMac = "11:22:33:44:55:66";
const string DestinationMac = "77:88:99:AA:BB:CC"; const string DestinationMac = "77:88:99:AA:BB:CC";
Packet expectedPacket = _random.NextEthernet(100, SourceMac, DestinationMac); Packet expectedPacket = _random.NextEthernetPacket(100, SourceMac, DestinationMac);
using (PacketCommunicator communicator = OpenOfflineDevice(numPacketsToSend, expectedPacket)) using (PacketCommunicator communicator = OpenOfflineDevice(numPacketsToSend, expectedPacket))
{ {
...@@ -293,7 +293,7 @@ namespace PcapDotNet.Core.Test ...@@ -293,7 +293,7 @@ namespace PcapDotNet.Core.Test
const string SourceMac = "11:22:33:44:55:66"; const string SourceMac = "11:22:33:44:55:66";
const string DestinationMac = "77:88:99:AA:BB:CC"; const string DestinationMac = "77:88:99:AA:BB:CC";
Packet expectedPacket = _random.NextEthernet(24, SourceMac, DestinationMac); Packet expectedPacket = _random.NextEthernetPacket(24, SourceMac, DestinationMac);
using (PacketCommunicator communicator = OpenOfflineDevice(numPacketsToSend, expectedPacket)) using (PacketCommunicator communicator = OpenOfflineDevice(numPacketsToSend, expectedPacket))
{ {
...@@ -322,7 +322,7 @@ namespace PcapDotNet.Core.Test ...@@ -322,7 +322,7 @@ namespace PcapDotNet.Core.Test
public static PacketCommunicator OpenOfflineDevice() public static PacketCommunicator OpenOfflineDevice()
{ {
return OpenOfflineDevice(10, _random.NextEthernet(100)); return OpenOfflineDevice(10, _random.NextEthernetPacket(100));
} }
......
...@@ -149,7 +149,7 @@ namespace PcapDotNet.Core.Test ...@@ -149,7 +149,7 @@ namespace PcapDotNet.Core.Test
packetsToSend = new List<Packet>(numPackets); packetsToSend = new List<Packet>(numPackets);
for (int i = 0; i != numPackets; ++i) for (int i = 0; i != numPackets; ++i)
{ {
Packet packetToSend = _random.NextEthernet(packetSize, timestamp, sourceMac, destinationMac); Packet packetToSend = _random.NextEthernetPacket(packetSize, timestamp, sourceMac, destinationMac);
queue.Enqueue(packetToSend); queue.Enqueue(packetToSend);
packetsToSend.Add(packetToSend); packetsToSend.Add(packetToSend);
timestamp = timestamp.AddSeconds(secondsBetweenTimestamps); timestamp = timestamp.AddSeconds(secondsBetweenTimestamps);
......
...@@ -40,18 +40,25 @@ ...@@ -40,18 +40,25 @@
<Reference Include="System.Core"> <Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference> </Reference>
<Reference Include="System.XML" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="BerkeleyPacketFilterTests.cs" /> <Compile Include="BerkeleyPacketFilterTests.cs" />
<Compile Include="DumpPacketsTests.cs" /> <Compile Include="DumpPacketsTests.cs" />
<Compile Include="MoreAssert.cs" /> <Compile Include="MoreAssert.cs" />
<Compile Include="LivePacketDeviceTests.cs" /> <Compile Include="LivePacketDeviceTests.cs" />
<Compile Include="MoreIpV4Option.cs" />
<Compile Include="MoreXElement.cs" />
<Compile Include="PacketHandler.cs" /> <Compile Include="PacketHandler.cs" />
<Compile Include="OfflinePacketDeviceTests.cs" /> <Compile Include="OfflinePacketDeviceTests.cs" />
<Compile Include="PacketSendBufferTests.cs" /> <Compile Include="PacketSendBufferTests.cs" />
<Compile Include="PcapDataLinkTests.cs" /> <Compile Include="PcapDataLinkTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PcapLibTests.cs" /> <Compile Include="PcapLibTests.cs" />
<Compile Include="WiresharkCompareTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\PcapDotNet.Base\PcapDotNet.Base.csproj"> <ProjectReference Include="..\PcapDotNet.Base\PcapDotNet.Base.csproj">
......
This diff is collapsed.
...@@ -6,9 +6,12 @@ using namespace System::Runtime::InteropServices; ...@@ -6,9 +6,12 @@ using namespace System::Runtime::InteropServices;
using namespace PcapDotNet::Core; using namespace PcapDotNet::Core;
// static // static
std::string MarshalingServices::ManagedToUnmanagedString(System::String^ managedString) std::string MarshalingServices::ManagedToUnmanagedString(String^ managedString)
{ {
// Marshal the managed string to unmanaged memory. // Marshal the managed string to unmanaged memory.
if (String::IsNullOrEmpty(managedString))
return std::string();
array<Byte>^ managedBytes = Encoding::ASCII->GetBytes(managedString); array<Byte>^ managedBytes = Encoding::ASCII->GetBytes(managedString);
pin_ptr<Byte> pinManagedBytes = &managedBytes[0]; pin_ptr<Byte> pinManagedBytes = &managedBytes[0];
Byte* unmanagedBytes = pinManagedBytes; Byte* unmanagedBytes = pinManagedBytes;
......
...@@ -14,25 +14,26 @@ using namespace System::Collections::Generic; ...@@ -14,25 +14,26 @@ using namespace System::Collections::Generic;
using namespace PcapDotNet::Packets; using namespace PcapDotNet::Packets;
using namespace PcapDotNet::Core; using namespace PcapDotNet::Core;
PacketCommunicator::PacketCommunicator(const char* source, int snapshotLength, PacketDeviceOpenAttributes attributes, int readTimeout, pcap_rmtauth *auth, SocketAddress^ netmask) // static
{ DateTime PacketCommunicator::MinimumPacketTimestamp::get()
// Open the device {
char errbuf[PCAP_ERRBUF_SIZE]; timeval zeroTimeValue;
pcap_t *pcapDescriptor = pcap_open(source, // name of the device zeroTimeValue.tv_sec = Int32::MinValue;
snapshotLength, // portion of the packet to capture zeroTimeValue.tv_usec = Int32::MinValue;
// 65536 guarantees that the whole packet will be captured on all the link layers DateTime result;
safe_cast<int>(attributes), Timestamp::PcapTimestampToDateTime(zeroTimeValue, result);
readTimeout, // read timeout return result;
auth, // authentication on the remote machine }
errbuf); // error buffer
if (pcapDescriptor == NULL)
{
throw gcnew InvalidOperationException("Unable to open the adapter. " + gcnew String(source) + " is not supported by WinPcap");
}
_pcapDescriptor = pcapDescriptor; // static
_ipV4Netmask = dynamic_cast<IpV4SocketAddress^>(netmask); DateTime PacketCommunicator::MaximumPacketTimestamp::get()
{
timeval maxTimeValue;
maxTimeValue.tv_sec = Int32::MaxValue;
maxTimeValue.tv_usec = Int32::MaxValue;
DateTime result;
Timestamp::PcapTimestampToDateTime(maxTimeValue, result);
return result;
} }
PcapDataLink PacketCommunicator::DataLink::get() PcapDataLink PacketCommunicator::DataLink::get()
...@@ -299,6 +300,43 @@ PacketCommunicator::~PacketCommunicator() ...@@ -299,6 +300,43 @@ PacketCommunicator::~PacketCommunicator()
pcap_close(_pcapDescriptor); pcap_close(_pcapDescriptor);
} }
// Internal
PacketCommunicator::PacketCommunicator(const char* source, int snapshotLength, PacketDeviceOpenAttributes attributes, int readTimeout, pcap_rmtauth *auth, SocketAddress^ netmask)
{
// Open the device
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *pcapDescriptor = pcap_open(source, // name of the device
snapshotLength, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
safe_cast<int>(attributes),
readTimeout, // read timeout
auth, // authentication on the remote machine
errbuf); // error buffer
if (pcapDescriptor == NULL)
{
throw gcnew InvalidOperationException("Unable to open the adapter. " + gcnew String(source) + " is not supported by WinPcap");
}
_pcapDescriptor = pcapDescriptor;
_ipV4Netmask = dynamic_cast<IpV4SocketAddress^>(netmask);
}
// Protected
pcap_t* PacketCommunicator::PcapDescriptor::get()
{
return _pcapDescriptor;
}
InvalidOperationException^ PacketCommunicator::BuildInvalidOperation(System::String^ errorMessage)
{
return PcapError::BuildInvalidOperation(errorMessage, _pcapDescriptor);
}
// Private
// static // static
Packet^ PacketCommunicator::CreatePacket(const pcap_pkthdr& packetHeader, const unsigned char* packetData, IDataLink^ dataLink) Packet^ PacketCommunicator::CreatePacket(const pcap_pkthdr& packetHeader, const unsigned char* packetData, IDataLink^ dataLink)
{ {
...@@ -333,16 +371,6 @@ void PacketCommunicator::AssertMode(PacketCommunicatorMode mode) ...@@ -333,16 +371,6 @@ void PacketCommunicator::AssertMode(PacketCommunicatorMode mode)
throw gcnew InvalidOperationException("Wrong Mode. Must be in mode " + mode.ToString() + " and not in mode " + Mode.ToString()); throw gcnew InvalidOperationException("Wrong Mode. Must be in mode " + mode.ToString() + " and not in mode " + Mode.ToString());
} }
InvalidOperationException^ PacketCommunicator::BuildInvalidOperation(System::String^ errorMessage)
{
return PcapError::BuildInvalidOperation(errorMessage, _pcapDescriptor);
}
pcap_t* PacketCommunicator::PcapDescriptor::get()
{
return _pcapDescriptor;
}
void PacketCommunicator::PacketHandler::Handle(unsigned char *, const struct pcap_pkthdr *packetHeader, const unsigned char *packetData) void PacketCommunicator::PacketHandler::Handle(unsigned char *, const struct pcap_pkthdr *packetHeader, const unsigned char *packetData)
{ {
++_packetCounter; ++_packetCounter;
......
...@@ -23,6 +23,16 @@ namespace PcapDotNet { namespace Core ...@@ -23,6 +23,16 @@ namespace PcapDotNet { namespace Core
public ref class PacketCommunicator abstract : System::IDisposable public ref class PacketCommunicator abstract : System::IDisposable
{ {
public: public:
static property System::DateTime MinimumPacketTimestamp
{
System::DateTime get();
}
static property System::DateTime MaximumPacketTimestamp
{
System::DateTime get();
}
/// <summary> /// <summary>
/// The link layer of an adapter. /// The link layer of an adapter.
/// </summary> /// </summary>
......
...@@ -6,9 +6,38 @@ ...@@ -6,9 +6,38 @@
#include "Pcap.h" #include "Pcap.h"
using namespace System; using namespace System;
using namespace System::Collections::Generic;
using namespace PcapDotNet::Core; using namespace PcapDotNet::Core;
using namespace PcapDotNet::Packets; using namespace PcapDotNet::Packets;
// static
void PacketDumpFile::Dump(String^ fileName, PcapDataLink dataLink, int snapshotLength, IEnumerable<Packet^>^ packets)
{
pcap_t* pcapDescriptor = pcap_open_dead(dataLink.Value, snapshotLength);
if (pcapDescriptor == NULL)
throw gcnew InvalidOperationException("Unable to open open a dead capture");
try
{
PacketDumpFile^ dumpFile = gcnew PacketDumpFile(pcapDescriptor, fileName);
try
{
for each (Packet^ packet in packets)
{
dumpFile->Dump(packet);
}
}
finally
{
dumpFile->~PacketDumpFile();
}
}
finally
{
pcap_close(pcapDescriptor);
}
}
void PacketDumpFile::Dump(Packet^ packet) void PacketDumpFile::Dump(Packet^ packet)
{ {
pcap_pkthdr header; pcap_pkthdr header;
......
#pragma once #pragma once
#include "PcapDeclarations.h" #include "PcapDeclarations.h"
#include "PcapDataLink.h"
namespace PcapDotNet { namespace Core namespace PcapDotNet { namespace Core
{ {
...@@ -10,6 +11,16 @@ namespace PcapDotNet { namespace Core ...@@ -10,6 +11,16 @@ namespace PcapDotNet { namespace Core
public ref class PacketDumpFile : System::IDisposable public ref class PacketDumpFile : System::IDisposable
{ {
public: public:
/// <summary>
/// Creates a dump file and saves the given packets to disk.
/// This method is useful when you've got packets to save but no device.
/// </summary>
/// <param name="fileName">The name of the dump file.</param>
/// <param name="dataLink">The data link of the packets saved globally in the dump file.</param>
/// <param name="snapshotLength">The dimension of the packet portion (in bytes) that is used when writing the packets. 65536 guarantees that the whole packet will be captured on all the link layers.</param>
/// <param name="packets">The packets to save to the dump file.</param>
static void Dump(System::String^ fileName, PcapDataLink dataLink, int snapshotLength, System::Collections::Generic::IEnumerable<Packets::Packet^>^ packets);
/// <summary> /// <summary>
/// Save a packet to disk. /// Save a packet to disk.
/// Outputs a packet to the "savefile" opened with PacketCommunicator.OpenDump(). /// Outputs a packet to the "savefile" opened with PacketCommunicator.OpenDump().
......
...@@ -30,6 +30,8 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -30,6 +30,8 @@ namespace PcapDotNet.Packets.TestUtils
return new Packet(buffer, DateTime.Now, random.NextDataLinkKind()); return new Packet(buffer, DateTime.Now, random.NextDataLinkKind());
} }
// Ethernet
public static MacAddress NextMacAddress(this Random random) public static MacAddress NextMacAddress(this Random random)
{ {
return new MacAddress(random.NextUInt48()); return new MacAddress(random.NextUInt48());
...@@ -40,7 +42,7 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -40,7 +42,7 @@ namespace PcapDotNet.Packets.TestUtils
return random.NextEnum(EthernetType.None); return random.NextEnum(EthernetType.None);
} }
public static Packet NextEthernet(this Random random, int packetSize, DateTime timestamp, MacAddress ethernetSource, MacAddress ethernetDestination) public static Packet NextEthernetPacket(this Random random, int packetSize, DateTime timestamp, MacAddress ethernetSource, MacAddress ethernetDestination)
{ {
if (packetSize < EthernetDatagram.HeaderLength) if (packetSize < EthernetDatagram.HeaderLength)
throw new ArgumentOutOfRangeException("packetSize", packetSize, "Must be at least the ethernet header length (" + EthernetDatagram.HeaderLength + ")"); throw new ArgumentOutOfRangeException("packetSize", packetSize, "Must be at least the ethernet header length (" + EthernetDatagram.HeaderLength + ")");
...@@ -50,26 +52,35 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -50,26 +52,35 @@ namespace PcapDotNet.Packets.TestUtils
random.NextDatagram(packetSize - EthernetDatagram.HeaderLength)); random.NextDatagram(packetSize - EthernetDatagram.HeaderLength));
} }
public static Packet NextEthernet(this Random random, int packetSize, DateTime timestamp, string ethernetSource, string ethernetDestination) public static Packet NextEthernetPacket(this Random random, int packetSize, DateTime timestamp, string ethernetSource, string ethernetDestination)
{ {
return random.NextEthernet(packetSize, timestamp, new MacAddress(ethernetSource), new MacAddress(ethernetDestination)); return random.NextEthernetPacket(packetSize, timestamp, new MacAddress(ethernetSource), new MacAddress(ethernetDestination));
} }
public static Packet NextEthernet(this Random random, int packetSize, string ethernetSource, string ethernetDestination) public static Packet NextEthernetPacket(this Random random, int packetSize, string ethernetSource, string ethernetDestination)
{ {
return random.NextEthernet(packetSize, DateTime.Now, ethernetSource, ethernetDestination); return random.NextEthernetPacket(packetSize, DateTime.Now, ethernetSource, ethernetDestination);
} }
public static Packet NextEthernet(this Random random, int packetSize) public static Packet NextEthernetPacket(this Random random, int packetSize)
{ {
return random.NextEthernet(packetSize, DateTime.Now, random.NextMacAddress(), random.NextMacAddress()); return random.NextEthernetPacket(packetSize, DateTime.Now, random.NextMacAddress(), random.NextMacAddress());
} }
// IPv4
public static IpV4Address NextIpV4Address(this Random random) public static IpV4Address NextIpV4Address(this Random random)
{ {
return new IpV4Address(random.NextUInt()); return new IpV4Address(random.NextUInt());
} }
public static IpV4Fragmentation NextIpV4Fragmentation(this Random random)
{
IpV4FragmentationOptions ipV4FragmentationFlags = random.NextEnum<IpV4FragmentationOptions>();
ushort ipV4FragmentationOffset = (ushort)(random.NextUShort() / 8 * 8);
return new IpV4Fragmentation(ipV4FragmentationFlags, ipV4FragmentationOffset);
}
public static IpV4OptionTimeOfDay NextIpV4OptionTimeOfDay(this Random random) public static IpV4OptionTimeOfDay NextIpV4OptionTimeOfDay(this Random random)
{ {
return new IpV4OptionTimeOfDay(random.NextUInt()); return new IpV4OptionTimeOfDay(random.NextUInt());
...@@ -199,6 +210,5 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -199,6 +210,5 @@ namespace PcapDotNet.Packets.TestUtils
} }
return new IpV4Options(options); return new IpV4Options(options);
} }
} }
} }
using System.Collections; using System;
using System.Collections;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
...@@ -57,7 +58,15 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -57,7 +58,15 @@ namespace PcapDotNet.Packets.IpV4
/// <summary> /// <summary>
/// The version (4). /// The version (4).
/// </summary> /// </summary>
public const int Version = 0x4; public const int DefaultVersion = 0x4;
/// <summary>
/// The header length in bytes.
/// </summary>
public int Version
{
get { return (this[Offset.VersionAndHeaderLength] & 0xF0) >> 4; }
}
/// <summary> /// <summary>
/// The header length in bytes. /// The header length in bytes.
...@@ -200,7 +209,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -200,7 +209,7 @@ namespace PcapDotNet.Packets.IpV4
IpV4Options options, int payloadLength) IpV4Options options, int payloadLength)
{ {
int headerLength = HeaderMinimumLength + options.BytesLength; int headerLength = HeaderMinimumLength + options.BytesLength;
buffer[offset + Offset.VersionAndHeaderLength] = (byte)((Version << 4) + headerLength / 4); buffer[offset + Offset.VersionAndHeaderLength] = (byte)((DefaultVersion << 4) + headerLength / 4);
buffer[offset + Offset.TypeOfService] = typeOfService; buffer[offset + Offset.TypeOfService] = typeOfService;
buffer.Write(offset + Offset.TotalLength, (ushort)(headerLength + payloadLength), Endianity.Big); buffer.Write(offset + Offset.TotalLength, (ushort)(headerLength + payloadLength), Endianity.Big);
buffer.Write(offset + Offset.Identification, identification, Endianity.Big); buffer.Write(offset + Offset.Identification, identification, Endianity.Big);
...@@ -239,8 +248,8 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -239,8 +248,8 @@ namespace PcapDotNet.Packets.IpV4
private ushort CalculateHeaderChecksum() private ushort CalculateHeaderChecksum()
{ {
uint sum = Sum16Bits(Buffer, StartOffset, Offset.HeaderChecksum) + uint sum = Sum16Bits(Buffer, StartOffset, Math.Min(Offset.HeaderChecksum, Length)) +
Sum16Bits(Buffer, StartOffset + Offset.HeaderChecksum + 2, HeaderLength - Offset.HeaderChecksum - 2); Sum16Bits(Buffer, StartOffset + Offset.HeaderChecksum + 2, Math.Min(HeaderLength, Length) - Offset.HeaderChecksum - 2);
return Sum16BitsToChecksum(sum); return Sum16BitsToChecksum(sum);
} }
......
...@@ -97,6 +97,11 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -97,6 +97,11 @@ namespace PcapDotNet.Packets.IpV4
get { return _pointedIndex; } get { return _pointedIndex; }
} }
/// <summary>
/// The number of timestamps this option holds (or can hold).
/// </summary>
public abstract int CountTimestamps { get; }
/// <summary> /// <summary>
/// The number of bytes this option will take. /// The number of bytes this option will take.
/// </summary> /// </summary>
......
...@@ -42,6 +42,14 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -42,6 +42,14 @@ namespace PcapDotNet.Packets.IpV4
{ {
} }
/// <summary>
/// The number of timestamps this option holds (or can hold).
/// </summary>
public override int CountTimestamps
{
get { return TimedRoute.Count(); }
}
/// <summary> /// <summary>
/// The pairs of addresses and timestamps where each timestamp time passed since midnight UT. /// The pairs of addresses and timestamps where each timestamp time passed since midnight UT.
/// </summary> /// </summary>
......
...@@ -34,6 +34,14 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -34,6 +34,14 @@ namespace PcapDotNet.Packets.IpV4
{ {
} }
/// <summary>
/// The number of timestamps this option holds (or can hold).
/// </summary>
public override int CountTimestamps
{
get { return Timestamps.Count(); }
}
/// <summary> /// <summary>
/// The timestamps as time passed since midnight UT. /// The timestamps as time passed since midnight UT.
/// </summary> /// </summary>
......
...@@ -78,9 +78,14 @@ namespace PcapDotNet.TestUtils ...@@ -78,9 +78,14 @@ namespace PcapDotNet.TestUtils
return ((((ulong)random.NextUInt()) << 32) + random.NextUInt()); return ((((ulong)random.NextUInt()) << 32) + random.NextUInt());
} }
public static DateTime NextDateTime(this Random random, DateTime minimumValue, DateTime maximumValue)
{
return new DateTime(random.NextLong(minimumValue.Ticks, maximumValue.Ticks + 1));
}
public static DateTime NextDateTime(this Random random) public static DateTime NextDateTime(this Random random)
{ {
return new DateTime(random.NextLong(DateTime.MinValue.Ticks, DateTime.MaxValue.Ticks + 1)); return random.NextDateTime(DateTime.MinValue, DateTime.MaxValue);
} }
public static T NextEnum<T>(this Random random, IEnumerable<T> valuesToIgnore) public static T NextEnum<T>(this Random random, IEnumerable<T> valuesToIgnore)
......
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