Deployment
The topics in this section provide information regarding the deployment of applications built with PCAP Filter.
Topics
User Mode Library
The user-mode library must be deployed to end-user systems along with the kernel-mode drivers; the version of the kernel-mode drivers on the end-user systems must be equal to or newer than the version of the user-mode library. Thus, when the user-mode library is installed or updated on end-user systems, it is required to ensure that the kernel-mode drivers already present in the system are updated to match the version of the installed user-mode library.
The user-mode library comes in two pieces, both of which must be deployed along with the application:
- A .NET assembly (managed), named callback.PCAPFilter.dll (or callback.PCAPFilter.NetStd.dll, for .NET Standard).
- A native dynamic library (unmanaged), named pcapfilter24.dll, available for both 32-bit (x86) and 64-bit (x64, ARM64) processor architectures.
When deploying the application, copy both the .NET assembly and the native library to the target system and place them next to the application's .exe file .
Alternatively, the native library may be placed into one of directories, the paths to which are contained in the PATH environment variable, such as C:\Windows\System32 (or C:\Windows\SysWOW64 when deploying a 32-bit application on a 64-bit Windows system).
The .NET assembly may be deployed to the Global Assembly Cache (GAC).
Loading of Native Library
Usually, .NET finds the native library when it is placed next to the assembly. But on some systems, it skips the directory of the assembly or even of the main application module. To ensure that this doesn't happen on a user's system when an application keeps the native library next to the .NET assembly, in the .NET Core 3.1 and .NET 5+ applications, you can use the DllImportResolver function as shown in the following snippet:
public static IntPtr NetFilterImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
bool loaded = false;
IntPtr libHandle = IntPtr.Zero;
if (!libraryName.Contains("callback.PCAPFilter"))
return IntPtr.Zero;
//Look for the native library next to the .NET assembly
loaded = NativeLibrary.TryLoad(libraryName, assembly, DllImportSearchPath.AssemblyDirectory, out libHandle);
//Look for the native library in the application's main directory
if (!loaded)
loaded = NativeLibrary.TryLoad(libraryName, assembly, DllImportSearchPath.ApplicationDirectory, out libHandle);
//Look for the native library using teh default .NET behavior
if (!loaded)
loaded = NativeLibrary.TryLoad(libraryName, assembly, searchPath, out libHandle);
return loaded ? libHandle : IntPtr.Zero;
}
...
NativeLibrary.SetDllImportResolver(Assembly.GetAssembly(typeof(NetFilter)), NetFilterImportResolver);
This code attempts to load the native library in the directory of the managed .NET assembly, and if not found then attempts to find the library in the application's main directory, and if not found then revert to the default .NET behavior.
Only one DllImportResolver function may be set for the assembly, so doing the above for one component is sufficient.
In the .NET Framework 4.x applications, one can use AppDomain.CurrentDomain.AssemblyResolve event for the same purpose.
NuGet Notes
After the NuGet package is added to a project, both the managed .NET assembly and the unmanaged native library will be copied to the project's output directory anytime the project is built. However, the exact files copied to the output directory for the native library will vary based on the project type:
- For .NET Core projects, a runtimes directory will be created in the output directory (if it does not already exist), and versions of the native library for each supported runtime identifer (RID) (e.g., win-x64) will be placed in the appropriate subdirectories. When the .NET Core application is distributed, the entire runtimes directory should be deployed alongside it.
- For other types of projects (.NET Framework, UWP), only the native library version specific to the currently selected platform target (e.g., x64) will be copied to the output directory.
- For .NET Framework projects specifically, please note that the project's platform target (Project > Properties > Build Tab > Platform target) must be set to a real architecture. If it is set to "Any CPU", no native library will be copied to the output directory.
The native library may alternatively be installed to the Windows system directory. This approach allows deploying both the 32-bit and 64-bit versions of the native library simultaneously, because each gets placed into the system directory that corresponds to the appropriate processor architecture.
Remember to deploy the drivers too, as they are an integral part of PCAP Filter.
General Information
The topics in this section provide general information about various aspects of the product's functionality.
IPMonitor Topics
The topics in this section provide additional information specific to the IPMonitor component.
Topics
Network Filter Library
The IPMonitor component requires a libpcap-compatible library to be installed in the system.
Windows
On Windows 10 and later, the component requires npcap to be installed. On Windows 7 and 8, either npcap or Winpcap can be used.
Linux
On Linux, the component will automatically attempt to locate libpcap if it is installed. The following commands may be used to install libpcap:
sudo apt install libpcap0.8
or
yum install libpcap
macOS
On macOS, libpcap must be present in the system. It can be installed from source by downloading the source code from the TCPDump site and building it locally.
Alternatively, libpcap can also be installed via the Homebrew package manager on macOS:
brew install libpcap
System Configuration in Linux and macOS
In systems like Linux, *BSD and macOS, capturing the network traffic requires special configuration, and the approach is different between Linux and macOS, supported by the product. In most cases, the superuser or root can capture the network traffic without any extra steps; below instructions are mostly applicable to limited users who want to use an application without elevating rights (or those who don't have root or sudo rights in the first place).
Linux
In Linux, the process that attempts to capture the traffic, must have cap_net_raw and cap_net_admin capabilities. These capabilities are added by the operator or setup script using a command similar to
sudo setcap cap_net_raw,cap_net_admin=eip {path-to-process}
Note that the setcap tool replaces the capabilities, so if the process must have other capabilities too, all of them must be included in the command.
macOS
In macOS, the procedure is more complicated. There are several devices related to packet capturing present, which can be listed using the command
ls -l /dev/bpf*
You will need to adjust permissions of those devices.
The common approach is to create a dedicated group, which will have read-write access to those devices, and add a user (the one who needs access to capturing) to this group. A simple sequence of steps here is:
sudo chgrp your_group /dev/bpf*
sudo chmod 660 /dev/bpf*
where "your_group" is the name of the group to which the user account belongs. If necessary, you can create a dedicated group for BPF monitoring, add a user to this group, then use the group as shown above.
The above changes should be done on every system start, so it may be necessary to configure a small launch daemon which will execute the above lines:
- Write the above or similar lines to a file, let's call it "set_bpf_perms.sh"
- make the script executable by using chmod:
chmod +x /path/to/set_bpf_perms.sh"
- Create a launch daemon plist file (e.g., com.user.bpf.plist) in /Library/LaunchDaemons:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.user.bpf</string> <key>ProgramArguments</key> <array> <string>/path/to/set_bpf_perms.sh</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> </dict> </plist> </xml>
- Load the daemon:
sudo launchctl load /Library/LaunchDaemons/com.user.bpf.plist
Additional information on BPF devices and libpcap can be found in the libpcap files.
Buffer Parameters
Some events include one or more parameters intended for use as a binary data buffer. Depending on the event, these parameters may contain data when the event is fired, or it may be expected that the application populates them with the desired amount of data during the event handler. Some events combine both paradigms and then expect the application to modify the data already present when the event is fired.
The documentation for such events will describe which of these cases applies to each buffer parameter. In all cases, buffer parameters point to a preallocated block of unmanaged memory, the size of which is specified by the parameter immediately following the buffer parameter. In cases in which data are to be written, be sure to write it directly to the pointed-to memory, do not change the value of the buffer parameter itself.
Buffer parameters are always of the IntPtr type; use the .NET Marshal.Copy() method to read and write data from and to the unmanaged memory region. When targeting newer .NET versions, such as .NET Standard 2.1 and later, applications can use the Span<T> and ReadOnlySpan<T> classes to access and modify the unmanaged memory region without extra data copying.