Skip to content

Commit 2aa3623

Browse files
trivalikrobo
authored and
robo
committed
npcap to work with similar behavior as winpcap, tests without physical adapter possible
1 parent 64a07d6 commit 2aa3623

File tree

114 files changed

+2729
-460
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+2729
-460
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ PcapDotNet/src/TestResults
77
PcapDotNet.DevelopersPack/3rdParty/
88
artifacts/
99
.vs/
10+
.idea/
11+
.vscode/
1012
TemporaryGeneratedFile_*
1113
*.cache
1214
*.csproj.FileListAbsolute.txt
@@ -15,6 +17,6 @@ TemporaryGeneratedFile_*
1517
*.pdb
1618
*.sdf
1719
*.suo
18-
*.vcxproj.user
20+
*.user
1921
*.db
2022
*.opendb

PcapDotNet/src/Directory.Build.props

+3-17
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,22 @@
1616
<AppendTargetFrameworkToOutputPath>True</AppendTargetFrameworkToOutputPath>
1717
<GenerateDocumentationFile>True</GenerateDocumentationFile>
1818
<IsPackable>False</IsPackable>
19+
<TargetFrameworks>net40;net80</TargetFrameworks>
1920
</PropertyGroup>
2021

2122
<!-- All none test projects -->
2223
<Choose>
2324
<When Condition=" !$(MSBuildProjectName.EndsWith('.Test')) ">
2425
<PropertyGroup>
25-
<TargetFrameworks>netstandard2.0</TargetFrameworks>
2626
<SignAssembly>true</SignAssembly>
2727
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)PcapDotNet.snk</AssemblyOriginatorKeyFile>
2828
</PropertyGroup>
2929
</When>
30-
</Choose>
31-
32-
<!-- All test projects -->
33-
<Choose>
34-
<When Condition=" $(MSBuildProjectName.EndsWith('.TestUtils')) ">
30+
<Otherwise>
3531
<PropertyGroup>
36-
<TargetFrameworks>netstandard2.0</TargetFrameworks>
3732
<GenerateDocumentationFile>False</GenerateDocumentationFile>
3833
</PropertyGroup>
39-
</When>
40-
</Choose>
41-
42-
<Choose>
43-
<When Condition=" $(MSBuildProjectName.EndsWith('.Test')) ">
44-
<PropertyGroup>
45-
<TargetFrameworks>net48;net8.0</TargetFrameworks>
46-
<GenerateDocumentationFile>False</GenerateDocumentationFile>
47-
</PropertyGroup>
48-
</When>
34+
</Otherwise>
4935
</Choose>
5036

5137
</Project>

PcapDotNet/src/PcapDotNet.Base.Test/PcapDotNet.Base.Test.csproj

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22

33
<ItemGroup>
44
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
5-
<PackageReference Include="xunit" Version="2.9.2" />
6-
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0">
5+
<PackageReference Include="xunit" Version="1.9.2" Condition="'$(TargetFramework)' == 'net40'" />
6+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" Condition="'$(TargetFramework)' == 'net40'">
7+
<PrivateAssets>all</PrivateAssets>
8+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
9+
</PackageReference>
10+
<PackageReference Include="xunit" Version="2.9.2" Condition="'$(TargetFramework)' == 'net80'" />
11+
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0" Condition="'$(TargetFramework)' == 'net80'">
712
<PrivateAssets>all</PrivateAssets>
813
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
914
</PackageReference>

PcapDotNet/src/PcapDotNet.Base.Test/UInt128Tests.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void CastToULongOverflow()
7070
}
7171
catch (Exception)
7272
{
73-
Assert.Fail();
73+
Assert.False(true);
7474
return;
7575
}
7676
Assert.Equal(overflow, (ulong)value);
@@ -251,4 +251,4 @@ public void ToStringTestFirstBitIsOne()
251251
Assert.Equal(ValueString, value.ToString("x32"));
252252
}
253253
}
254-
}
254+
}

PcapDotNet/src/PcapDotNet.Base/IListExtensions.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace PcapDotNet.Base
1111
public static class IListExtensions
1212
// ReSharper restore InconsistentNaming
1313
{
14+
#if !NET7_0_OR_GREATER
1415
/// <summary>
1516
/// Wraps a list with a ReadOnlyCollection.
1617
/// </summary>
@@ -21,7 +22,7 @@ public static ReadOnlyCollection<T> AsReadOnly<T>(this IList<T> list)
2122
{
2223
return new ReadOnlyCollection<T>(list);
2324
}
24-
25+
#endif
2526
/// <summary>
2627
/// Returns an enumerable of all the elements in the given list starting in a specific offset and taking no more than a specific count.
2728
/// </summary>
@@ -37,4 +38,4 @@ public static IEnumerable<T> Range<T>(this IList<T> list, int offset, int count)
3738
yield return list[i];
3839
}
3940
}
40-
}
41+
}

PcapDotNet/src/PcapDotNet.Core.Extensions/LivePacketDeviceExtensions.cs

+18-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Management;
55
using System.Net.NetworkInformation;
66
using Microsoft.Win32;
7+
using PcapDotNet.Core.Native;
78
using PcapDotNet.Packets;
89
using PcapDotNet.Packets.Ethernet;
910

@@ -31,6 +32,8 @@ public static string GetGuid(this LivePacketDevice livePacketDevice)
3132
throw new ArgumentNullException("livePacketDevice");
3233

3334
string livePacketDeviceName = livePacketDevice.Name;
35+
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
36+
return livePacketDeviceName;
3437
if (!livePacketDeviceName.StartsWith(NamePrefix, StringComparison.Ordinal))
3538
{
3639
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
@@ -50,11 +53,14 @@ public static string GetGuid(this LivePacketDevice livePacketDevice)
5053
/// <exception cref="InvalidOperationException">When the PNPDeviceID cannot be retrieved from the registry.</exception>
5154
public static string GetPnpDeviceId(this LivePacketDevice livePacketDevice)
5255
{
56+
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
57+
throw new InvalidOperationException("Platform not supported");
58+
5359
string guid = livePacketDevice.GetGuid();
5460

5561
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(NetworkConnectionConfigKey + @"\" + guid + @"\Connection"))
5662
{
57-
string pnpDeviceId = key.GetValue("PnpInstanceID") as string;
63+
string pnpDeviceId = key?.GetValue("PnpInstanceID") as string;
5864
if (pnpDeviceId == null)
5965
throw new InvalidOperationException("Could not find PNP Device ID in the registry");
6066
return pnpDeviceId;
@@ -75,7 +81,7 @@ public static NetworkInterface GetNetworkInterface(this LivePacketDevice livePac
7581
throw new ArgumentNullException("livePacketDevice");
7682

7783
string guid = GetGuid(livePacketDevice);
78-
return NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(networkInterface => networkInterface.Id == guid);
84+
return Interop.Pcap.GetAllNetworkInterfacesByDotNet().FirstOrDefault(networkInterface => networkInterface.Id == guid);
7985
}
8086

8187
/// <summary>
@@ -95,6 +101,12 @@ public static MacAddress GetMacAddress(this LivePacketDevice livePacketDevice)
95101
return new MacAddress(addressBytes.ReadUInt48(0, Endianity.Big));
96102
}
97103

104+
if (Environment.OSVersion.Platform != PlatformID.Unix && Environment.OSVersion.Platform != PlatformID.MacOSX
105+
&& livePacketDevice.Name == "rpcap://\\Device\\NPF_Loopback")
106+
{
107+
return new MacAddress();
108+
}
109+
98110
return livePacketDevice.GetMacAddressWmi();
99111
}
100112

@@ -107,6 +119,9 @@ public static MacAddress GetMacAddress(this LivePacketDevice livePacketDevice)
107119
/// <exception cref="InvalidOperationException">When the <see cref="MacAddress"/> cannot be retrieved using WMI.</exception>
108120
private static MacAddress GetMacAddressWmi(this LivePacketDevice livePacketDevice)
109121
{
122+
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
123+
throw new InvalidOperationException("No MAC Address on device: " + livePacketDevice.Name);
124+
110125
string pnpDeviceId = livePacketDevice.GetPnpDeviceId();
111126
string escapedPnpDeviceId = pnpDeviceId.Replace(@"\", @"\\");
112127

@@ -128,4 +143,4 @@ private static MacAddress GetMacAddressWmi(this LivePacketDevice livePacketDevic
128143
throw new InvalidOperationException("No MAC Address for WMI instance with PNP Device ID: " + pnpDeviceId);
129144
}
130145
}
131-
}
146+
}

PcapDotNet/src/PcapDotNet.Core.Extensions/NetworkInterfaceExtensions.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Linq;
33
using System.Net.NetworkInformation;
4+
using System.Runtime.InteropServices;
45

56
namespace PcapDotNet.Core.Extensions
67
{
@@ -21,7 +22,9 @@ public static LivePacketDevice GetLivePacketDevice(this NetworkInterface network
2122
if (networkInterface == null)
2223
throw new ArgumentNullException("networkInterface");
2324

24-
return LivePacketDevice.AllLocalMachine.FirstOrDefault(device => device.Name == LivePacketDeviceExtensions.NamePrefix + networkInterface.Id);
25+
return LivePacketDevice.AllLocalMachine.FirstOrDefault(device => Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX
26+
? device.Name == networkInterface.Id
27+
: device.Name == LivePacketDeviceExtensions.NamePrefix + networkInterface.Id);
2528
}
2629
}
27-
}
30+
}

PcapDotNet/src/PcapDotNet.Core.Extensions/PcapDotNet.Core.Extensions.csproj

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
</ItemGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
11-
<PackageReference Include="System.Management" Version="8.0.0" />
10+
<Reference Include="System.Management" />
1211
</ItemGroup>
1312

14-
</Project>
13+
<ItemGroup>
14+
<PackageReference Include="System.Management" Version="8.0.0" Condition="'$(TargetFramework)' == 'net80'" />
15+
</ItemGroup>
16+
17+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace PcapDotNet.Core.Extensions
6+
{
7+
/// <summary>
8+
/// Extension methods for Task class.
9+
/// </summary>
10+
public static class TaskExtensions
11+
{
12+
/// <summary>
13+
/// Creates a Task that will complete after a time delay.
14+
/// </summary>
15+
/// <param name="delay">The time span to wait before completing the returned Task</param>
16+
/// <returns>A Task that represents the time delay</returns>
17+
/// <exception cref="ArgumentOutOfRangeException">
18+
/// The <paramref name="delay"/> is less than -1 or greater than the maximum allowed timer duration.
19+
/// </exception>
20+
/// <remarks>
21+
/// After the specified time delay, the Task is completed in RanToCompletion state.
22+
/// </remarks>
23+
public static Task Delay(TimeSpan delay)
24+
{
25+
// timer inaccuracy https://github.com/dotnet/runtime/issues/100455
26+
#if NETCOREAPP1_0_OR_GREATER
27+
return Task.Delay(delay.Add(TimeSpan.FromMilliseconds(1))); // +1 is to workaround, random return less than 1 ms too early
28+
#else
29+
var tcs = new TaskCompletionSource<object>();
30+
Timer timer = null;
31+
timer = new Timer(_ =>
32+
{
33+
tcs.SetResult(null);
34+
timer.Dispose(); // prevent GC
35+
});
36+
timer.Change((long)delay.TotalMilliseconds + 1, -1); // +1 is to workaround, random return less than 1 ms too early
37+
return tcs.Task;
38+
#endif
39+
}
40+
}
41+
}

PcapDotNet/src/PcapDotNet.Core.Test/BerkeleyPacketFilterTests.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,15 @@ namespace PcapDotNet.Core.Test
1010
/// Summary description for BerkeleyPacketFilterTests
1111
/// </summary>
1212
[ExcludeFromCodeCoverage]
13-
[Collection(nameof(LivePacketDeviceTests))]
1413
public class BerkeleyPacketFilterTests
1514
{
15+
#if !REAL
16+
public BerkeleyPacketFilterTests()
17+
{
18+
TestablePcapPal.UseTestPal();
19+
}
20+
#endif
21+
1622
[Fact]
1723
public void BadFilterErrorTest()
1824
{
@@ -22,6 +28,7 @@ public void BadFilterErrorTest()
2228
}
2329
}
2430

31+
// fails on REAL unix because no packets are sent
2532
[Fact]
2633
public void NoCommunicatorConstructorTest()
2734
{
@@ -41,6 +48,7 @@ public void NoCommunicatorConstructorTest()
4148
}
4249
}
4350

51+
// fails on REAL unix because no packets are sent
4452
[Fact]
4553
public void NoCommunicatorConstructorWithNetmaskTest()
4654
{

PcapDotNet/src/PcapDotNet.Core.Test/LivePacketDeviceExtensionsTests.cs

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Diagnostics.CodeAnalysis;
3+
using System.Linq;
34
using PcapDotNet.Core.Extensions;
45
using Xunit;
56

@@ -9,24 +10,47 @@ namespace PcapDotNet.Core.Test
910
/// Summary description for LivePacketDeviceExtensionsTests
1011
/// </summary>
1112
[ExcludeFromCodeCoverage]
12-
[Collection(nameof(LivePacketDeviceTests))]
1313
public class LivePacketDeviceExtensionsTests
1414
{
15+
#if !REAL
16+
public LivePacketDeviceExtensionsTests()
17+
{
18+
TestablePcapPal.UseTestPal();
19+
}
20+
#endif
21+
1522
[Fact]
1623
public void GetNetworkInterfaceNullTest()
1724
{
1825
Assert.Throws<ArgumentNullException>(() => LivePacketDeviceExtensions.GetNetworkInterface(null));
1926
}
20-
21-
[Fact(Skip ="NullRefExcetion for loopback device")]
27+
28+
// this test tests on linux other paths!
29+
[Fact]
2230
public void GetMacAddressTest()
2331
{
2432
foreach (LivePacketDevice device in LivePacketDevice.AllLocalMachine)
2533
{
26-
_ = device.GetMacAddress();
34+
if ((Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
35+
&& (device.Name == "any" || device.Name == "bluetooth-monitor" || device.Name == "nflog"
36+
|| device.Name == "nfqueue" || device.Name == "dbus-system" || device.Name == "dbus-session"))
37+
{
38+
continue;
39+
}
40+
41+
_ = device.GetMacAddress();
2742
}
2843
}
2944

45+
// this test tests on linux other paths!
46+
[Fact]
47+
public void GetMacAddress_Loopback_ReturnsZeroMac()
48+
{
49+
var loopback = LivePacketDevice.AllLocalMachine.First(n => (n.Attributes & DeviceAttributes.Loopback) != 0);
50+
51+
Assert.Equal(Packets.Ethernet.MacAddress.Zero, loopback.GetMacAddress());
52+
}
53+
3054
[Fact]
3155
public void GetGuidNullDeviceTest()
3256
{

0 commit comments

Comments
 (0)