From 1c38eb5348eff425aa66bee767016afd5356c40d Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Mar 2023 18:42:55 +0900 Subject: [PATCH 01/13] Use new OperatingSystem APIs on .NET 6+ --- SharpPcap/LibPcap/BpfProgram.cs | 7 +++++- SharpPcap/LibPcap/LibPcapLiveDevice.cs | 25 +++++++++++++------ .../LibPcapSafeNativeMethods.Encoding.cs | 8 +++++- .../LibPcapSafeNativeMethods.Interop.cs | 14 ++++++----- .../LibPcapSafeNativeMethods.Resolver.cs | 24 +++++++++++++++--- SharpPcap/LibPcap/LibPcapSafeNativeMethods.cs | 21 +++++++++++++--- SharpPcap/LibPcap/PcapHeader.cs | 16 ++++++++++-- SharpPcap/LibPcap/PcapInterface.cs | 8 +++++- SharpPcap/Pcap.cs | 8 +++++- SharpPcap/SharpPcap.csproj | 2 +- SharpPcap/Statistics/StatisticsDevice.cs | 8 +++++- SharpPcap/Tunneling/TunnelDevice.cs | 8 +++++- 12 files changed, 120 insertions(+), 29 deletions(-) diff --git a/SharpPcap/LibPcap/BpfProgram.cs b/SharpPcap/LibPcap/BpfProgram.cs index 77790df2..0520ea70 100644 --- a/SharpPcap/LibPcap/BpfProgram.cs +++ b/SharpPcap/LibPcap/BpfProgram.cs @@ -34,7 +34,12 @@ public class BpfProgram : SafeHandleZeroOrMinusOneIsInvalid // Requires calls to pcap_compile to be non-concurrent to avoid crashes due to known lack of thread-safety // See https://github.com/chmorgan/sharppcap/issues/311 // Problem of thread safety does not affect Windows - private static readonly bool ThreadSafeCompile = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + private static readonly bool ThreadSafeCompile = +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif || Pcap.LibpcapVersion >= new Version(1, 8, 0); private static readonly object SyncCompile = new object(); diff --git a/SharpPcap/LibPcap/LibPcapLiveDevice.cs b/SharpPcap/LibPcap/LibPcapLiveDevice.cs index 0c661876..cf8daf6d 100644 --- a/SharpPcap/LibPcap/LibPcapLiveDevice.cs +++ b/SharpPcap/LibPcap/LibPcapLiveDevice.cs @@ -116,7 +116,13 @@ public override void Open(DeviceConfiguration configuration) var immediate_supported = Pcap.LibpcapVersion >= new Version(1, 5, 0); // Check if we can do immediate by setting mintocopy to 0 // See https://www.tcpdump.org/manpages/pcap_set_immediate_mode.3pcap.html - var mintocopy_supported = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + var mintocopy_supported = +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ; var errbuf = new StringBuilder(Pcap.PCAP_ERRBUF_SIZE); //will hold errors @@ -170,8 +176,6 @@ public override void Open(DeviceConfiguration configuration) } else { - // We got authentication, so this is an rpcap device - var auth = RemoteAuthentication.CreateAuth(credentials); // Immediate and MaxResponsiveness are the same thing if (immediateMode == true) { @@ -181,12 +185,11 @@ public override void Open(DeviceConfiguration configuration) immediateMode = null; try { - Handle = LibPcapSafeNativeMethods.pcap_open( + Handle = LibPcapSafeNativeMethods.pcap_open_live( Name, // name of the device configuration.Snaplen, // portion of the packet to capture. - (short)mode, // flags - (short)configuration.ReadTimeout, // read timeout - ref auth, // authentication + (int)mode, // flags + configuration.ReadTimeout, // read timeout errbuf); // error buffer } catch (TypeLoadException) @@ -255,7 +258,13 @@ public override void Open(DeviceConfiguration configuration) } base.Open(configuration); // retrieve the file descriptor of the adapter for use with poll() - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if ( +#if NET6_0_OR_GREATER + OperatingSystem.IsLinux() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Linux) +#endif + ) { FileDescriptor = LibPcapSafeNativeMethods.pcap_get_selectable_fd(Handle); } diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Encoding.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Encoding.cs index 829f1f78..d9966af0 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Encoding.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Encoding.cs @@ -37,7 +37,13 @@ internal static partial class LibPcapSafeNativeMethods private static Encoding ConfigureStringEncoding() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (! +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ) { // libpcap always use UTF-8 when not on Windows return Encoding.UTF8; diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs index 7e8308b7..4d6b7d52 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs @@ -41,7 +41,7 @@ internal static partial class LibPcapSafeNativeMethods // This file is called $assembly_name.dll.config and is placed in the // same directory as the assembly // See http://www.mono-project.com/Interop_with_Native_Libraries#Library_Names - private const string PCAP_DLL = "wpcap"; + private const string PCAP_DLL = "pcap"; [DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)] internal extern static int pcap_init( @@ -66,13 +66,15 @@ internal extern static int pcap_findalldevs_ex( [DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)] internal extern static void pcap_freealldevs(IntPtr /* pcap_if_t * */ alldevs); + /// + /// Open a generic source in order to capture / send (WinPcap only) traffic. + /// [DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)] - internal extern static PcapHandle /* pcap_t* */ pcap_open( + internal extern static PcapHandle /* pcap_t* */ pcap_open_live( [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] string dev, - int packetLen, - int flags, - int read_timeout, - ref pcap_rmtauth rmtauth, + int snaplen, + int promisc, + int to_ms, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder errbuf ); diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs index 5c5437bb..ee8bc307 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs @@ -39,7 +39,13 @@ internal static partial class LibPcapSafeNativeMethods static LibPcapSafeNativeMethods() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if ( +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ) { SetDllDirectory(Path.Combine(Environment.SystemDirectory, "Npcap")); } @@ -70,7 +76,13 @@ public static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSe var names = new List(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if ( +#if NET6_0_OR_GREATER + OperatingSystem.IsLinux() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Linux) +#endif + ) { names.Add("libpcap.so"); names.Add("libpcap.so.0"); @@ -78,7 +90,13 @@ public static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSe names.Add("libpcap.so.1"); } - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if ( +#if NET6_0_OR_GREATER + OperatingSystem.IsMacOS() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.OSX) +#endif + ) { names.Add("libpcap.dylib"); } diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.cs index add75571..b9b7d51d 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.cs @@ -37,13 +37,23 @@ internal static partial class LibPcapSafeNativeMethods internal static PcapError pcap_setbuff(PcapHandle /* pcap_t */ adapter, int bufferSizeInBytes) { - return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + return +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +# endif ? _pcap_setbuff(adapter, bufferSizeInBytes) : PcapError.PlatformNotSupported; } internal static PcapError pcap_setmintocopy(PcapHandle /* pcap_t */ adapter, int sizeInBytes) { - return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + return +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif ? _pcap_setmintocopy(adapter, sizeInBytes) : PcapError.PlatformNotSupported; } @@ -111,7 +121,12 @@ internal static int pcap_get_tstamp_precision(PcapHandle /* pcap_t* p */ adapter internal static PcapHandle pcap_open_handle_offline_with_tstamp_precision( SafeHandle handle, uint precision, StringBuilder errbuf) { - var pointer = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + var pointer = +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +# endif ? _pcap_hopen_offline_with_tstamp_precision(handle, precision, errbuf) : _pcap_fopen_offline_with_tstamp_precision(handle, precision, errbuf); if (pointer == IntPtr.Zero) diff --git a/SharpPcap/LibPcap/PcapHeader.cs b/SharpPcap/LibPcap/PcapHeader.cs index baec2cf5..fb65fdb0 100644 --- a/SharpPcap/LibPcap/PcapHeader.cs +++ b/SharpPcap/LibPcap/PcapHeader.cs @@ -30,8 +30,20 @@ namespace SharpPcap.LibPcap /// public class PcapHeader : ICaptureHeader { - private static readonly bool isMacOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); - private static readonly bool is32BitTs = IntPtr.Size == 4 || RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + private static readonly bool isMacOSX = +#if NET6_0_OR_GREATER + OperatingSystem.IsMacOS() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.OSX) +#endif + ; + private static readonly bool is32BitTs = IntPtr.Size == 4 || +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ; internal static readonly int MemorySize = GetTimevalSize() + sizeof(uint) + sizeof(uint); diff --git a/SharpPcap/LibPcap/PcapInterface.cs b/SharpPcap/LibPcap/PcapInterface.cs index 0fd19d7d..b774f534 100644 --- a/SharpPcap/LibPcap/PcapInterface.cs +++ b/SharpPcap/LibPcap/PcapInterface.cs @@ -143,7 +143,13 @@ internal PcapInterface(pcap_if pcapIf, NetworkInterface networkInterface, Remote } } } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + else if ( +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ) { FriendlyName = WindowsNativeMethods.GetInterfaceAlias(Name); } diff --git a/SharpPcap/Pcap.cs b/SharpPcap/Pcap.cs index f9988152..ff8e37b4 100644 --- a/SharpPcap/Pcap.cs +++ b/SharpPcap/Pcap.cs @@ -108,7 +108,13 @@ static Pcap() // FIXME: need to resolve the discrepency at some point AF_PACKET = 17; - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (! +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ) { AF_INET6 = 10; // value for linux from socket.h } diff --git a/SharpPcap/SharpPcap.csproj b/SharpPcap/SharpPcap.csproj index daa227f7..b14b3a2c 100644 --- a/SharpPcap/SharpPcap.csproj +++ b/SharpPcap/SharpPcap.csproj @@ -1,6 +1,6 @@  - netstandard2.0 + netstandard2.0;net6.0 6.2.5 A packet capture framework for .NET Tamir Gal, Chris Morgan and others diff --git a/SharpPcap/Statistics/StatisticsDevice.cs b/SharpPcap/Statistics/StatisticsDevice.cs index e278e9a9..153d620c 100644 --- a/SharpPcap/Statistics/StatisticsDevice.cs +++ b/SharpPcap/Statistics/StatisticsDevice.cs @@ -33,7 +33,13 @@ public class StatisticsDevice : IPcapDevice { private readonly LibPcapLiveDevice LiveDevice; - private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + private static readonly bool IsWindows = +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ; /// /// Constructs a new PcapDevice based on a 'pcapIf' struct diff --git a/SharpPcap/Tunneling/TunnelDevice.cs b/SharpPcap/Tunneling/TunnelDevice.cs index b22b95c4..f823bfd8 100644 --- a/SharpPcap/Tunneling/TunnelDevice.cs +++ b/SharpPcap/Tunneling/TunnelDevice.cs @@ -18,7 +18,13 @@ public partial class TunnelDevice : BaseLiveDevice, ILiveDevice private static ITunnelDriver GetDriver() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if ( +#if NET6_0_OR_GREATER + OperatingSystem.IsWindows() +#else + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) +#endif + ) { return WinTapDriver.Instance; } From d3875aa090f18d9fcbad278a8a4ed0b34654f04e Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Mar 2023 00:38:47 +0900 Subject: [PATCH 02/13] Preserve netfx compatibility --- SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs index 4d6b7d52..59c78042 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs @@ -41,7 +41,14 @@ internal static partial class LibPcapSafeNativeMethods // This file is called $assembly_name.dll.config and is placed in the // same directory as the assembly // See http://www.mono-project.com/Interop_with_Native_Libraries#Library_Names - private const string PCAP_DLL = "pcap"; + private const string PCAP_DLL = +#if NET6_0_OR_GREATER + "pcap" +#else + "wpcap" +#endif + ; + [DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)] internal extern static int pcap_init( From dc8775f88aebc22cb7327bfe779de95c632e2c62 Mon Sep 17 00:00:00 2001 From: Steven He Date: Mon, 6 Mar 2023 14:57:23 +0900 Subject: [PATCH 03/13] Use native library resolver for Windows only --- .../LibPcapSafeNativeMethods.Resolver.cs | 41 +------------------ SharpPcap/LibPcap/NativeLibraryHelper.cs | 11 +++-- 2 files changed, 7 insertions(+), 45 deletions(-) diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs index ee8bc307..52b1193a 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs @@ -48,9 +48,6 @@ static LibPcapSafeNativeMethods() ) { SetDllDirectory(Path.Combine(Environment.SystemDirectory, "Npcap")); - } - else - { RegisterResolver(); } StringEncoding = ConfigureStringEncoding(); @@ -74,42 +71,8 @@ public static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSe return IntPtr.Zero; } - var names = new List(); - - if ( -#if NET6_0_OR_GREATER - OperatingSystem.IsLinux() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Linux) -#endif - ) - { - names.Add("libpcap.so"); - names.Add("libpcap.so.0"); - names.Add("libpcap.so.0.8"); - names.Add("libpcap.so.1"); - } - - if ( -#if NET6_0_OR_GREATER - OperatingSystem.IsMacOS() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.OSX) -#endif - ) - { - names.Add("libpcap.dylib"); - } - - foreach (var name in names) - { - if (NativeLibraryHelper.TryLoad(name, out var handle)) - { - return handle; - } - } - - return IntPtr.Zero; + return NativeLibraryHelper.TryLoad("wpcap.dll", out var library) + ? library : IntPtr.Zero; } } } diff --git a/SharpPcap/LibPcap/NativeLibraryHelper.cs b/SharpPcap/LibPcap/NativeLibraryHelper.cs index 0b36e099..3d38fb52 100644 --- a/SharpPcap/LibPcap/NativeLibraryHelper.cs +++ b/SharpPcap/LibPcap/NativeLibraryHelper.cs @@ -6,15 +6,10 @@ namespace SharpPcap.LibPcap { class NativeLibraryHelper { - public delegate IntPtr DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath); - private static readonly Type NativeLibraryType; - static NativeLibraryHelper() - { - NativeLibraryType = typeof(DllImportSearchPath).Assembly + private static readonly Type NativeLibraryType = typeof(DllImportSearchPath).Assembly .GetType("System.Runtime.InteropServices.NativeLibrary"); - } public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver) { @@ -23,6 +18,9 @@ public static void SetDllImportResolver(Assembly assembly, DllImportResolver res return; } +#if NET6_0_OR_GREATER + NativeLibrary.SetDllImportResolver(assembly, (lib, asm, path) => resolver(lib, asm, path)); +#else var dllImportResolverType = typeof(DllImportSearchPath).Assembly .GetType("System.Runtime.InteropServices.DllImportResolver"); @@ -39,6 +37,7 @@ public static void SetDllImportResolver(Assembly assembly, DllImportResolver res assembly, Delegate.CreateDelegate(dllImportResolverType, resolver, "Invoke") }); +#endif } public static bool TryLoad(string libraryPath, out IntPtr handle) From 97ab64c0771ecefc3803449fd6c6638a4928549e Mon Sep 17 00:00:00 2001 From: Steven He Date: Mon, 6 Mar 2023 13:30:38 +0000 Subject: [PATCH 04/13] Use pcap_open --- SharpPcap/LibPcap/LibPcapLiveDevice.cs | 9 ++++++--- SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs | 9 +++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/SharpPcap/LibPcap/LibPcapLiveDevice.cs b/SharpPcap/LibPcap/LibPcapLiveDevice.cs index cf8daf6d..1e7aa8a1 100644 --- a/SharpPcap/LibPcap/LibPcapLiveDevice.cs +++ b/SharpPcap/LibPcap/LibPcapLiveDevice.cs @@ -176,6 +176,8 @@ public override void Open(DeviceConfiguration configuration) } else { + // We got authentication, so this is an rpcap device + var auth = RemoteAuthentication.CreateAuth(credentials); // Immediate and MaxResponsiveness are the same thing if (immediateMode == true) { @@ -185,11 +187,12 @@ public override void Open(DeviceConfiguration configuration) immediateMode = null; try { - Handle = LibPcapSafeNativeMethods.pcap_open_live( + Handle = LibPcapSafeNativeMethods.pcap_open( Name, // name of the device configuration.Snaplen, // portion of the packet to capture. - (int)mode, // flags - configuration.ReadTimeout, // read timeout + (short)mode, // flags + (short)configuration.ReadTimeout, // read timeout + ref auth, // authentication errbuf); // error buffer } catch (TypeLoadException) diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs index 59c78042..89b78675 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs @@ -77,11 +77,12 @@ internal extern static int pcap_findalldevs_ex( /// Open a generic source in order to capture / send (WinPcap only) traffic. /// [DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)] - internal extern static PcapHandle /* pcap_t* */ pcap_open_live( + internal extern static PcapHandle /* pcap_t* */ pcap_open( [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] string dev, - int snaplen, - int promisc, - int to_ms, + int packetLen, + int flags, + int read_timeout, + ref pcap_rmtauth rmtauth, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PcapStringMarshaler))] StringBuilder errbuf ); From ba89ff27543c0383851014bfb9139682a52e96bd Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 6 Mar 2023 23:30:17 +0900 Subject: [PATCH 05/13] Apply review feedback Co-authored-by: Ayoub Kaanich --- SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs index 89b78675..289c44f2 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs @@ -74,7 +74,7 @@ internal extern static int pcap_findalldevs_ex( internal extern static void pcap_freealldevs(IntPtr /* pcap_if_t * */ alldevs); /// - /// Open a generic source in order to capture / send (WinPcap only) traffic. + /// Open a generic source in order to capture / send traffic. /// [DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)] internal extern static PcapHandle /* pcap_t* */ pcap_open( From 7c9c08d8a129f0fef3691a89a3099fb6a5e18a1c Mon Sep 17 00:00:00 2001 From: Steven He Date: Mon, 6 Mar 2023 23:37:19 +0900 Subject: [PATCH 06/13] Revert unnecessary changes --- SharpPcap/LibPcap/BpfProgram.cs | 7 +------ SharpPcap/LibPcap/PcapHeader.cs | 16 ++-------------- SharpPcap/LibPcap/PcapInterface.cs | 8 +------- SharpPcap/Pcap.cs | 8 +------- SharpPcap/Statistics/StatisticsDevice.cs | 8 +------- SharpPcap/Tunneling/TunnelDevice.cs | 8 +------- 6 files changed, 7 insertions(+), 48 deletions(-) diff --git a/SharpPcap/LibPcap/BpfProgram.cs b/SharpPcap/LibPcap/BpfProgram.cs index 0520ea70..77790df2 100644 --- a/SharpPcap/LibPcap/BpfProgram.cs +++ b/SharpPcap/LibPcap/BpfProgram.cs @@ -34,12 +34,7 @@ public class BpfProgram : SafeHandleZeroOrMinusOneIsInvalid // Requires calls to pcap_compile to be non-concurrent to avoid crashes due to known lack of thread-safety // See https://github.com/chmorgan/sharppcap/issues/311 // Problem of thread safety does not affect Windows - private static readonly bool ThreadSafeCompile = -#if NET6_0_OR_GREATER - OperatingSystem.IsWindows() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) -#endif + private static readonly bool ThreadSafeCompile = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || Pcap.LibpcapVersion >= new Version(1, 8, 0); private static readonly object SyncCompile = new object(); diff --git a/SharpPcap/LibPcap/PcapHeader.cs b/SharpPcap/LibPcap/PcapHeader.cs index fb65fdb0..baec2cf5 100644 --- a/SharpPcap/LibPcap/PcapHeader.cs +++ b/SharpPcap/LibPcap/PcapHeader.cs @@ -30,20 +30,8 @@ namespace SharpPcap.LibPcap /// public class PcapHeader : ICaptureHeader { - private static readonly bool isMacOSX = -#if NET6_0_OR_GREATER - OperatingSystem.IsMacOS() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.OSX) -#endif - ; - private static readonly bool is32BitTs = IntPtr.Size == 4 || -#if NET6_0_OR_GREATER - OperatingSystem.IsWindows() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) -#endif - ; + private static readonly bool isMacOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + private static readonly bool is32BitTs = IntPtr.Size == 4 || RuntimeInformation.IsOSPlatform(OSPlatform.Windows); internal static readonly int MemorySize = GetTimevalSize() + sizeof(uint) + sizeof(uint); diff --git a/SharpPcap/LibPcap/PcapInterface.cs b/SharpPcap/LibPcap/PcapInterface.cs index b774f534..0fd19d7d 100644 --- a/SharpPcap/LibPcap/PcapInterface.cs +++ b/SharpPcap/LibPcap/PcapInterface.cs @@ -143,13 +143,7 @@ internal PcapInterface(pcap_if pcapIf, NetworkInterface networkInterface, Remote } } } - else if ( -#if NET6_0_OR_GREATER - OperatingSystem.IsWindows() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) -#endif - ) + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { FriendlyName = WindowsNativeMethods.GetInterfaceAlias(Name); } diff --git a/SharpPcap/Pcap.cs b/SharpPcap/Pcap.cs index ff8e37b4..f9988152 100644 --- a/SharpPcap/Pcap.cs +++ b/SharpPcap/Pcap.cs @@ -108,13 +108,7 @@ static Pcap() // FIXME: need to resolve the discrepency at some point AF_PACKET = 17; - if (! -#if NET6_0_OR_GREATER - OperatingSystem.IsWindows() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) -#endif - ) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { AF_INET6 = 10; // value for linux from socket.h } diff --git a/SharpPcap/Statistics/StatisticsDevice.cs b/SharpPcap/Statistics/StatisticsDevice.cs index 153d620c..e278e9a9 100644 --- a/SharpPcap/Statistics/StatisticsDevice.cs +++ b/SharpPcap/Statistics/StatisticsDevice.cs @@ -33,13 +33,7 @@ public class StatisticsDevice : IPcapDevice { private readonly LibPcapLiveDevice LiveDevice; - private static readonly bool IsWindows = -#if NET6_0_OR_GREATER - OperatingSystem.IsWindows() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) -#endif - ; + private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); /// /// Constructs a new PcapDevice based on a 'pcapIf' struct diff --git a/SharpPcap/Tunneling/TunnelDevice.cs b/SharpPcap/Tunneling/TunnelDevice.cs index f823bfd8..b22b95c4 100644 --- a/SharpPcap/Tunneling/TunnelDevice.cs +++ b/SharpPcap/Tunneling/TunnelDevice.cs @@ -18,13 +18,7 @@ public partial class TunnelDevice : BaseLiveDevice, ILiveDevice private static ITunnelDriver GetDriver() { - if ( -#if NET6_0_OR_GREATER - OperatingSystem.IsWindows() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) -#endif - ) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return WinTapDriver.Instance; } From 8b2ff750811d0ef2bea8c2f3039e9c663f7a6f0c Mon Sep 17 00:00:00 2001 From: Steven He Date: Mon, 6 Mar 2023 23:41:37 +0900 Subject: [PATCH 07/13] Fix an issue where stacktrace doesn't preserve due to rethrow --- SharpPcap/LibPcap/PcapDevice.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharpPcap/LibPcap/PcapDevice.cs b/SharpPcap/LibPcap/PcapDevice.cs index 1e69ec7f..f8e35e1c 100644 --- a/SharpPcap/LibPcap/PcapDevice.cs +++ b/SharpPcap/LibPcap/PcapDevice.cs @@ -541,10 +541,10 @@ public static IEnumerable GetSequence(ICaptureDevice dev, bool maskE break; packet = e.GetPacket(); } - catch (PcapException pe) + catch (PcapException) { if (!maskExceptions) - throw pe; + throw; } if (packet == null) From 5eff35b90f61c087ff3aec81968b523e3c823ae9 Mon Sep 17 00:00:00 2001 From: Steven He Date: Tue, 7 Mar 2023 14:23:38 +0900 Subject: [PATCH 08/13] Apply review feedbacks --- .../LibPcapSafeNativeMethods.Encoding.cs | 8 +------ .../LibPcapSafeNativeMethods.Resolver.cs | 24 +++---------------- SharpPcap/LibPcap/PcapDevice.cs | 4 ++-- 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Encoding.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Encoding.cs index d9966af0..829f1f78 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Encoding.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Encoding.cs @@ -37,13 +37,7 @@ internal static partial class LibPcapSafeNativeMethods private static Encoding ConfigureStringEncoding() { - if (! -#if NET6_0_OR_GREATER - OperatingSystem.IsWindows() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) -#endif - ) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // libpcap always use UTF-8 when not on Windows return Encoding.UTF8; diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs index 8a20f332..90cfc7ce 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs @@ -71,13 +71,7 @@ public static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSe return IntPtr.Zero; } - if ( -#if NET6_0_OR_GREATER - OperatingSystem.IsWindows() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) -#endif - ) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return NativeLibraryHelper.TryLoad("wpcap.dll", out var library) ? library : IntPtr.Zero; @@ -85,13 +79,7 @@ public static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSe var names = new List(); - if ( -#if NET6_0_OR_GREATER - OperatingSystem.IsLinux() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.Linux) -#endif - ) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { names.Add("libpcap.so"); names.Add("libpcap.so.0"); @@ -99,13 +87,7 @@ public static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSe names.Add("libpcap.so.1"); } - if ( -#if NET6_0_OR_GREATER - OperatingSystem.IsMacOS() -#else - RuntimeInformation.IsOSPlatform(OSPlatform.OSX) -#endif - ) + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { names.Add("libpcap.dylib"); } diff --git a/SharpPcap/LibPcap/PcapDevice.cs b/SharpPcap/LibPcap/PcapDevice.cs index f8e35e1c..58976762 100644 --- a/SharpPcap/LibPcap/PcapDevice.cs +++ b/SharpPcap/LibPcap/PcapDevice.cs @@ -541,10 +541,10 @@ public static IEnumerable GetSequence(ICaptureDevice dev, bool maskE break; packet = e.GetPacket(); } - catch (PcapException) + catch (PcapException ex) { if (!maskExceptions) - throw; + throw ex; } if (packet == null) From 66eb37007b518387b4d05adbbdc98431b753f5e7 Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 30 May 2023 17:40:29 +0900 Subject: [PATCH 09/13] Update PcapDevice.cs --- SharpPcap/LibPcap/PcapDevice.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharpPcap/LibPcap/PcapDevice.cs b/SharpPcap/LibPcap/PcapDevice.cs index 58976762..1e69ec7f 100644 --- a/SharpPcap/LibPcap/PcapDevice.cs +++ b/SharpPcap/LibPcap/PcapDevice.cs @@ -541,10 +541,10 @@ public static IEnumerable GetSequence(ICaptureDevice dev, bool maskE break; packet = e.GetPacket(); } - catch (PcapException ex) + catch (PcapException pe) { if (!maskExceptions) - throw ex; + throw pe; } if (packet == null) From f46b461364e7ef9043ca443535eb0727a699568e Mon Sep 17 00:00:00 2001 From: Steven He Date: Thu, 2 May 2024 15:02:21 +0900 Subject: [PATCH 10/13] Fixes --- SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs | 9 +-------- SharpPcap/Tunneling/WinTap/WinTapDriver.cs | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs index b970922e..7eb69f0b 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Interop.cs @@ -25,14 +25,7 @@ internal static partial class LibPcapSafeNativeMethods // This file is called $assembly_name.dll.config and is placed in the // same directory as the assembly // See http://www.mono-project.com/Interop_with_Native_Libraries#Library_Names - private const string PCAP_DLL = -#if NET6_0_OR_GREATER - "pcap" -#else - "wpcap" -#endif - ; - + private const string PCAP_DLL = "wpcap"; [DllImport(PCAP_DLL, CallingConvention = CallingConvention.Cdecl)] internal extern static int pcap_init( diff --git a/SharpPcap/Tunneling/WinTap/WinTapDriver.cs b/SharpPcap/Tunneling/WinTap/WinTapDriver.cs index dc9a5777..407b5614 100644 --- a/SharpPcap/Tunneling/WinTap/WinTapDriver.cs +++ b/SharpPcap/Tunneling/WinTap/WinTapDriver.cs @@ -81,7 +81,7 @@ internal static void SetMediaStatus(SafeFileHandle handle, bool connected) int value = connected ? 1 : 0; Span inBuffer = stackalloc byte[4]; Span outBuffer = stackalloc byte[4]; - MemoryMarshal.Write(inBuffer, ref value); + MemoryMarshal.Write(inBuffer, in value); TapControl(handle, TapIoControl.SetMediaStatus, inBuffer, ref outBuffer); } From 680828937e976a9a1220283ab17cc01166fa8b26 Mon Sep 17 00:00:00 2001 From: Steven He Date: Thu, 2 May 2024 15:03:50 +0900 Subject: [PATCH 11/13] Add net8.0 tfm --- SharpPcap/SharpPcap.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharpPcap/SharpPcap.csproj b/SharpPcap/SharpPcap.csproj index 01219f18..e8b680d5 100644 --- a/SharpPcap/SharpPcap.csproj +++ b/SharpPcap/SharpPcap.csproj @@ -7,7 +7,7 @@ SPDX-License-Identifier: MIT --> - netstandard2.0;net6.0 + netstandard2.0;net6.0;net8.0 6.3.0 A packet capture framework for .NET Tamir Gal, Chris Morgan and others From b8e7d127f2ba080d464be2cb3233bf142fc9892d Mon Sep 17 00:00:00 2001 From: Steven He Date: Thu, 2 May 2024 15:06:21 +0900 Subject: [PATCH 12/13] Revert unnecessary changes --- .../LibPcap/LibPcapSafeNativeMethods.Resolver.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs index a72e630f..d5a70b29 100644 --- a/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs +++ b/SharpPcap/LibPcap/LibPcapSafeNativeMethods.Resolver.cs @@ -33,7 +33,10 @@ static LibPcapSafeNativeMethods() { SetDllDirectory(Path.Combine(Environment.SystemDirectory, "Npcap")); } - RegisterResolver(); + else + { + RegisterResolver(); + } StringEncoding = ConfigureStringEncoding(); } @@ -55,12 +58,6 @@ public static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSe return IntPtr.Zero; } - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return NativeLibraryHelper.TryLoad("wpcap.dll", out var library) - ? library : IntPtr.Zero; - } - var names = new List(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) From 191eb3e7fc73e48ecf22280f12578167d7840461 Mon Sep 17 00:00:00 2001 From: Steven He Date: Thu, 2 May 2024 15:08:26 +0900 Subject: [PATCH 13/13] Fix building --- SharpPcap/Tunneling/WinTap/WinTapDriver.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SharpPcap/Tunneling/WinTap/WinTapDriver.cs b/SharpPcap/Tunneling/WinTap/WinTapDriver.cs index 407b5614..e308ac81 100644 --- a/SharpPcap/Tunneling/WinTap/WinTapDriver.cs +++ b/SharpPcap/Tunneling/WinTap/WinTapDriver.cs @@ -81,7 +81,11 @@ internal static void SetMediaStatus(SafeFileHandle handle, bool connected) int value = connected ? 1 : 0; Span inBuffer = stackalloc byte[4]; Span outBuffer = stackalloc byte[4]; +#if NET8_0_OR_GREATER MemoryMarshal.Write(inBuffer, in value); +#else + MemoryMarshal.Write(inBuffer, ref value); +#endif TapControl(handle, TapIoControl.SetMediaStatus, inBuffer, ref outBuffer); }