NetworkInspector.Filter 0.17.0

dotnet add package NetworkInspector.Filter --version 0.17.0
                    
NuGet\Install-Package NetworkInspector.Filter -Version 0.17.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NetworkInspector.Filter" Version="0.17.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NetworkInspector.Filter" Version="0.17.0" />
                    
Directory.Packages.props
<PackageReference Include="NetworkInspector.Filter" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NetworkInspector.Filter --version 0.17.0
                    
#r "nuget: NetworkInspector.Filter, 0.17.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NetworkInspector.Filter@0.17.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NetworkInspector.Filter&version=0.17.0
                    
Install as a Cake Addin
#tool nuget:?package=NetworkInspector.Filter&version=0.17.0
                    
Install as a Cake Tool

NetworkInspector.Filter

NuGet Downloads .NET 10 License: MIT

Wireshark-style display filters for NetworkInspector packets: udp.dstport == 53, ip.src in {10.0.0.1, 10.0.0.2}, tcp && !tls. Expressions are compiled once to native code and checked against the protocol stack, so a typo is a compile error with a "did you mean" hint, not a silent non-match.

Highlights

  • Familiar syntax. Protocol presence, comparisons, and / or / not, sets, ranges, contains, matches, byte slices, len(), IPv4/IPv6/MAC literals, field aliases (eth.addr).
  • Compiled. Expressions become .NET expression trees compiled by the JIT; evaluation short-circuits.
  • Fast over large captures. With a PacketIndex, a filter prunes the candidate packets with presence bitmaps before it evaluates a single packet.
  • Beyond Wireshark. Subtree scopes ($udp { udp.dstport == 53 }) bind conditions to one protocol instance; flank(...) detects value edges across packets within a time or packet window.
  • Works without a field tree. A FilterObserver evaluates during a skip parse, for high-throughput pipelines.
  • Editor support. Filter.GetCompletions returns completions at the caret; errors carry position, length, and a suggestion.
  • Safe on untrusted expressions. Bounded nesting (64) and term count (1024), linear-time regex where possible and a timeout otherwise, errors as values instead of exceptions.
  • Used everywhere. Session listeners and both ni CLI commands (--filter) use this language.

Install

dotnet add package NetworkInspector.Filter
dotnet add package NetworkInspector.Protocols

Quick Start

using NetworkInspector.Core;
using NetworkInspector.Core.Ids;
using NetworkInspector.Core.Settings;
using NetworkInspector.Filter;
using NetworkInspector.Filter.Errors;
using NetworkInspector.Protocols;
using NetworkInspector.Values;

StackBuilder builder = new(new SettingsManager(), new FrameInterfaceRegistry());
builder.RegisterStandardProtocols();
using Stack stack = builder.Build();

// Compile once against the stack: unknown names fail here, with a suggestion.
if (!Filter.TryCompile("udp.dstport == 53 && ip.ttl > 32", stack, out Filter? filter, out FilterError? error))
{
    Console.Error.WriteLine(error); // [Kind] at position (length n): message
    return;
}

// Ethernet / IPv4 192.168.1.1 -> 192.168.1.2 / UDP 12345 -> 53
byte[] raw = Convert.FromHexString(
    "001122334455" + "66778899AABB" + "0800" +
    "4500001C" + "12344000" + "4011A549" + "C0A80101" + "C0A80102" +
    "30390035" + "00080000");
Frame frame = Frame.Create(new FrameId(0), Timestamp.FromSecs(0), raw,
    LinkType.Ethernet, FrameInterfaceId.Invalid, stack.FrameInterfaceRegistry).Value;

ParseOptions options = new(); // filters evaluate the field tree
if (!Packet.TryParse(new PacketId(0), stack, frame, in options, out Packet? packet, out ParseFailure failure)
    || packet is null)
{
    throw new InvalidOperationException(failure.ToString());
}

// false = no verdict (for example a runtime error), not "no match".
if (!filter.TryIsMatch(packet, out bool matched, out FilterError? evalError))
{
    throw new InvalidOperationException(evalError.ToString());
}

Console.WriteLine(matched); // True

Inside a namespace that starts with NetworkInspector, the name Filter refers to the namespace; use an alias such as using PacketFilter = NetworkInspector.Filter.Filter;.

Language At A Glance

Expression Meaning
tcp, !dns Protocol present / absent
ip.src == 10.0.0.1 Comparison (==, !=, <, <=, >, >=)
tcp.port in {80, 443}, udp.port in 1024..65535 Set and range membership
http.host contains "example" Ordinal substring
http.user_agent matches "(?i)curl" .NET regular expression
udp.payload[0:2] == 00:2a, len(udp.payload) > 100 Byte slices and lengths
eth.addr == FF:FF:FF:FF:FF:FF Alias: any member field matches
$udp { udp.dstport == 53 } Subtree scope: one UDP instance satisfies all conditions
flank(can.id, changed, within: 10ms) Stateful edge detection across packets

A repeated field matches if any occurrence matches. Keywords are case-insensitive; and, or, not work as well as &&, ||, !. Full grammar and semantics: FILTER_GUIDE.md.

Common Tasks

Filter Many Packets With The Presence Index

Record a PacketIndex during parsing and pass it to the filter; packets that cannot match are rejected from the index without evaluating the tree:

using NetworkInspector.Core.Index;

PacketIndex index = new(stack);
ParseOptions indexed = new(index: index);
// ... Packet.TryParse(..., in indexed, ...) for every frame ...
filter.TryIsMatch(packet, index, out bool matched, out FilterError? evalError);

TryBuildCandidates(index, out RoaringBitmap? candidates) returns the whole candidate set at once.

Offer Completions In An Editor

FilterCompletions completions = Filter.GetCompletions("udp.dst", caretPosition: 7, stack);
foreach (FilterCompletionItem item in completions.Items)
{
    Console.WriteLine($"{item.Text} ({item.Kind})"); // udp.dstport (Field)
}

ReplaceStart and ReplaceLength give the span to replace. Completion is thread-safe and caches one name catalog per stack.

Evaluate During A Skip Parse

Filter.Compile(expression, stack, in FilterObserverOptions options) returns a FilterObserver. Pass it as a parse observer with FieldTreeMode.Skip and read IsMatch after the parse (TryReadMatch for flank). Observers reject subtree scopes and protocol presence without a container field (NeedsFieldTree).

Errors

FilterError has Kind (FilterErrorKind), Message, Position, Length, and Suggestion. ToString() prints [Kind] at P (length L): Message.

  • Compile errors: LexerError, SyntaxError, UnknownField (with a suggestion), TypeMismatch, InvalidValue, UnsupportedFeature, StackRequired, NeedsFieldTree.
  • Evaluation errors poison the filter (fail closed) until ResetState() or TryDerive(newStack, …).
  • An empty expression compiles to Filter.AlwaysMatch and needs no stack.

Limits And Thread-Safety Notes

  • A Filter instance is single-threaded; compile one per thread or derive copies with TryDerive. Filter.AlwaysMatch is immutable and shared.
  • Results are cached per PacketId by default. Turn the cache off with FilterCompileOptions.EnableMatchCache = false for forward-only pipelines that never revisit a packet.
  • Stateful filters (flank) require ascending packet ids and do not use index pruning.
  • Expressions nest at most 64 levels and hold at most 1024 terms; matches patterns that need backtracking run with RegexTimeout (default 1 s).
  • Runtime code generation: not compatible with NativeAOT or trimming.

Learn More

License

MIT License

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on NetworkInspector.Filter:

Package Downloads
NetworkInspector.Sessions

Session orchestration for NetworkInspector. Coordinates frame sources, protocol stack parsing, pull-based listeners, and background jobs.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.17.0 0 10/17/2026
0.16.0 0 10/17/2026
0.15.0 93 10/9/2026
0.14.0 91 10/8/2026
0.13.0 107 9/27/2026
0.12.0 110 9/17/2026
0.11.0 115 9/10/2026
0.10.0 113 9/8/2026
0.9.0 121 9/2/2026
0.8.0 133 8/28/2026
0.7.0 122 8/27/2026
0.6.0 126 8/21/2026