Ether.Net
1.1.0
dotnet add package Ether.Net --version 1.1.0
NuGet\Install-Package Ether.Net -Version 1.1.0
<PackageReference Include="Ether.Net" Version="1.1.0" />
<PackageVersion Include="Ether.Net" Version="1.1.0" />
<PackageReference Include="Ether.Net" />
paket add Ether.Net --version 1.1.0
#r "nuget: Ether.Net, 1.1.0"
#addin nuget:?package=Ether.Net&version=1.1.0
#tool nuget:?package=Ether.Net&version=1.1.0
Ether.Net
Ether.Net is a modern, lightweight and asynchronous wrapper around the popular SharpPcap library, designed to simplify the capture and analysis of packets and metrics in .NET applications, using modern technologies such as IAsyncEnumerable
for reading packets, Channel
for storing them, etc. It provides an API for high-performance and non-blocking network packet capture.
NOTICE!
Before using the library, you need to install the Npcap utility. This allows Windows software to capture raw network traffic.
Usage
Preparation
Before you start capturing network traffic, you need to select the device on which you want to capture packets. To do this, use the DeviceObserver
class and the GetAvailableDevices()
static method:
var devices = DeviceObserver.GetAvailableDevices();
The method will return IList<ICaptureDevice>
, from there you will get the network device you need.
Now you can create an instance of the PacketCaptureProvider
class by passing the selected device as the constructor arguments:
var pcapProvider = new PacketCaptureProvider(devices.First());
There are cases when you need to initialize the PacketCaptureProvider
without knowing in advance what device to pass to the constructor. To do this, you can use the SetDeviceToCaptureFrom()
method to pass the device when it is available, leaving the constructor empty during initialization:
var pcapProvider = new PacketCaptureProvider();
var devices = DeviceObserver.GetAvailableDevices();
pcapProvider.SetDeviceToCaptureFrom(devices.First());
You can also specify capture options by passing an instance of the CaptureOptions
class to the constructor:
var pcapProvider = new PacketCaptureProvider(devices.First(), new CaptureOptions { Filter = string.Empty, Promiscuous = true, ReadTimeoutMs = 1000 });
For more convenient filter construction or if you don't know the BPF (Berkeley Packet Filter) syntax for filtering, you can use BPFBuilder
to build the BPF expression:
string filter = BPFBuilder.Create()
.Protocol(BPFProto.Ip)
.Build();
var pcapProvider = new PacketCaptureProvider(devices.First(), new CaptureOptions { Filter = filter });
Capturing And Extracting
Now you can start capturing network packets using the Start()
method:
pcapProvider.Start();
Using await foreach
and CaptureAsync()
method, you can asynchronously get the next intercepted packet in its raw form:
await foreach (var rawPacket in pcapProvider.CaptureAsync())
{
Console.WriteLine(rawPacket.Length);
}
To retrieve the packet of the required protocol, use the TryParseTo<T>()
extension method:
rawPacket.TryParseTo<IPv4Packet>(out var ipv4)
You can see all supported protocols in the PacketDotNet library.
If you don't know in advance what protocol the received packet is, you can parse the raw packet in FlatNetworkPacket
using ParseToFlat()
method.
This class extracts and exposes all known protocol levels in the packet as nullable properties. By examining its properties, you can easily determine all the extracted protocols:
var flat = rawPacket.ParseToFlat();
Also with FlatNetworkPacket
you can extract all protocol types present in a compressed network packet as an array:
var actualTypes = flat.GetActualPacketTypes();
To stop capturing packets on a device, use the Stop()
method:
pcapProvider.Stop();
You can also retrieve all metrics using GetMetrics()
calculated within the current packet capture session, and the overridden ToString()
method will allow you to get human-readable metrics as a string:
var metrics = pcapProvider.GetMetrics();
Console.WriteLine(metrics.ToString());
Below are all the metrics you can get:
- Total number of packets successfully captured
- Total number of bytes received across all captured packets
- Number of packets dropped by the capture mechanism (according to SharpPcap)
- Number of packets dropped by the interface itself (according to SharpPcap)
- List of exceptions that occurred during the capture session
- Timestamp when capture started
- Timestamp when capture completed
- Total duration of the capture session
- Average number of packets received per second since the start of capture
- Average number of bytes received per second since the start of capture
- Average size of a single packet in bytes
- Maximum observed packet throughput per second
- Maximum observed byte throughput per second
- Average time between packets in milliseconds
Utilities
You can integrate PacketCaptureProvider
into your ASP.NET application by registering it in the dependency container. After that, you can get an instance of IPacketCaptureProvider
from the dependency container inside your services and controllers:
builder.Services.AddPacketCaptureProvider(df =>
{
var devices = DeviceObserver.GetAvailableDevices();
return devices.First();
});
You also have the option to try to resolve an IP address to a domain name using the TryResolveHostname()
method.
In addition, there is a GetIpGeolocationAsync()
method that allows you to asynchronously get the geolocation of an IP address using the public API from ip-api.com. Be mindful of request limits for free usage! These methods are provided by the EtherNetUtils
class. Below is an example of usage:
var utils = new EtherNetUtils();
var task = Task.Run(async () => await Task.Delay(60_000));
await foreach (var rawPacket in pcapProvider.CaptureAsync())
{
if (task.IsCompleted)
break;
if (rawPacket.TryParseTo<IPv4Packet>(out var ipv4) == false)
continue;
var geo = await utils.GetIpGeolocationAsync(ipv4.SourceAddress);
utils.TryResolveHostname(ipv4.SourceAddress, out var hostname);
Console.WriteLine($"Hostname: {hostname ?? "unknown"}\nGeo: {geo}\n");
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.5)
- PacketDotNet (>= 1.4.8)
- SharpPcap (>= 6.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
a few fixes + additional methods