NDIS 6 Lightweight Filter (LWF) WinpkFilter 3.x

Windows Packet Filter

High-performance raw Ethernet frame filtering, packet inspection, and packet injection for Windows. Filter and manipulate network traffic in user mode without writing kernel drivers.

Driver I/O: Shared-Memory Fast I/O
Throughput: Multi-Gigabit Throughput
Language APIs: C++, C# (.NET), Rust, Go
Platforms: Modern Windows • x86 / x64 / ARM64
Looking for commercial licensing or driver source code? Explore Commercial Licensing →

Complete Control Over Raw Ethernet Traffic

Windows Packet Filter intercepts network traffic directly between the protocol drivers (TCP/IP) and the network interface driver, granting bidirectional packet inspection and manipulation.

01

Capture

Intercept Layer 2 raw Ethernet frames before protocol stack processing.

02

Inspect

Parse full Ethernet, IPv4/IPv6, TCP/UDP headers and payloads.

03

Filter / Modify

Drop, pass, or rewrite intercepted frames in user-mode memory.

04

Inject

Re-inject packets into the network stack or forward to physical adapters.

Native APIs for C++, C# (.NET), Rust, and Go

Intercept packets from a TCP/IP-bound adapter and reinject them unchanged in both directions using tunnel mode. The same packet-processing model is available through the C++, .NET, Rust, and Go APIs.

#include <iostream>
#include <memory>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <tchar.h>
#include "common.h"
#include "ndisapi.h"

// Use a dedicated test adapter: tunnel mode temporarily diverts its traffic.
// Stops after 100 packet notifications or 5 seconds without a notification.
struct SessionCleanup {
    CNdisApi& api;
    HANDLE adapter;
    HANDLE event;
    bool event_registered = false;
    bool tunnel_enabled = false;

    bool finish() {
        bool ok = true;
        if (tunnel_enabled) {
            ADAPTER_MODE mode{};
            mode.hAdapterHandle = adapter;
            if (!api.SetAdapterMode(&mode)) {
                std::cerr << "Could not restore adapter mode.\n";
                ok = false;
            } else {
                tunnel_enabled = false;
            }
        }
        if (event_registered) {
            if (!api.SetPacketEvent(adapter, nullptr)) {
                std::cerr << "Could not unregister packet event.\n";
                ok = false;
            } else {
                event_registered = false;
            }
        }
        if (event) {
            if (!CloseHandle(event)) {
                std::cerr << "Could not close packet event: " << GetLastError() << '\n';
                ok = false;
            } else {
                event = nullptr;
            }
        }
        return ok;
    }
    ~SessionCleanup() { finish(); }
};

int main()
{
    auto api = std::make_unique<CNdisApi>();
    if (!api->IsDriverLoaded()) {
        std::cerr << "WinpkFilter driver is not loaded.\n";
        return 1;
    }

    TCP_AdapterList adapters{};
    if (!api->GetTcpipBoundAdaptersInfo(&adapters) || adapters.m_nAdapterCount == 0) {
        std::cerr << "No TCP/IP bound adapters found.\n";
        return 1;
    }

    HANDLE adapter = adapters.m_nAdapterHandle[0];
    ADAPTER_MODE mode{};
    mode.hAdapterHandle = adapter;
    if (!api->GetAdapterMode(&mode)) {
        std::cerr << "Could not query adapter mode.\n";
        return 1;
    }
    if (mode.dwFlags != 0) {
        std::cerr << "Adapter filtering is already active; select an idle dedicated test adapter.\n";
        return 1;
    }
    HANDLE event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
    if (!event) {
        std::cerr << "Could not create packet event: " << GetLastError() << '\n';
        return 1;
    }
    SessionCleanup cleanup{*api, adapter, event};
    if (!api->SetPacketEvent(adapter, event)) {
        std::cerr << "Could not register packet event.\n";
        return 1;
    }
    cleanup.event_registered = true;

    mode.dwFlags = MSTCP_FLAG_SENT_TUNNEL | MSTCP_FLAG_RECV_TUNNEL;
    if (!api->SetAdapterMode(&mode)) {
        std::cerr << "Could not enter tunnel mode.\n";
        return 1;
    }
    cleanup.tunnel_enabled = true;

    INTERMEDIATE_BUFFER packet{};
    ETH_REQUEST request{};
    request.hAdapterHandle = adapter;
    request.EthPacket.Buffer = &packet;

    // Process a bounded number of notification cycles for this minimal example
    constexpr int DEMO_WAKEUPS = 100;
    constexpr DWORD IDLE_TIMEOUT_MS = 5000;
    for (int i = 0; i < DEMO_WAKEUPS; ++i) {
        DWORD status = WaitForSingleObject(event, IDLE_TIMEOUT_MS);
        if (status == WAIT_TIMEOUT) {
            std::cout << "No packet notification for 5 seconds; stopping. Generate traffic on the selected test adapter to capture packets.\n";
            break;
        }
        if (status != WAIT_OBJECT_0) {
            std::cerr << "Packet-event wait failed: " << GetLastError() << '\n';
            return 1;
        }
        if (!ResetEvent(event)) {
            std::cerr << "Could not reset packet event: " << GetLastError() << '\n';
            return 1;
        }

        // FALSE ends this drain of the adapter's currently queued packets.
        while (api->ReadPacket(&request)) {
            BOOL sent = packet.m_dwDeviceFlags == PACKET_FLAG_ON_SEND
                ? api->SendPacketToAdapter(&request)
                : api->SendPacketToMstcp(&request);
            if (!sent) {
                std::cerr << "Could not reinject packet.\n";
                return 1;
            }
        }
    }
    return cleanup.finish() ? 0 : 1;
}
Looking for maximum kernel performance? The Source Code License allows compiling custom C/C++ inspection routines directly inside the ndisrd.sys kernel filter driver.

Driver Position in the Windows Network Stack

WinpkFilter attaches as an NDIS 6.x Lightweight Filter (LWF) directly below all Windows protocol drivers (TCP/IP) and above the physical or virtual network interface drivers.

Driver Position in the Windows Network Stack Diagram showing driver position of ndisrd.sys in the Windows network stack between TCP/IP protocol drivers and network interface miniports, communicating with ndisapi.dll in user space. USER MODE KERNEL MODE (Ring 0) User-Space Application Firewall, SOCKS5 Proxy, VPN, DPI, WireSock, ProxiFyre NDISAPI / Driver APIs Native DLL/static; .NET DLL; Rust/Go direct I/O Standard I/O • Optional Fast I/O (FAST_IO_SECTION) User / Kernel I/O Boundary Windows TCP/IP Protocol Stack tcpip.sys • IPv4 / IPv6 Protocol Drivers Windows Packet Filter Driver (ndisrd.sys) NDIS 6.x Lightweight Filter (LWF) • In-Kernel Filtering • Bidirectional Interception and Injection NDIS Miniport Drivers & Physical / Virtual Network Interfaces Ethernet (802.3) • Wi-Fi (802.11) • Mobile Broadband (PPP/WWAN) • Virtual Adapters
STANDARD I/O Synchronous • Per-Adapter Queues

Standard IOCTL queues provide synchronous packet reading and reinjection for supported network adapters.

Application → ndisapi.dll → IOCTL Queues → ndisrd.sys
OPTIONAL FAST I/O Shared Memory • Low Syscall Overhead

High-throughput path utilizing shared memory (FAST_IO_SECTION) between user space and kernel driver for low-latency packet processing.

Application → ndisapi.dll → FAST_IO_SECTION → ndisrd.sys

Full Layer 2 Inspection

Because the driver sits below tcpip.sys, packets are captured with complete 802.3 Ethernet headers intact. You can filter non-IP protocols (ARP, PPPoE, custom ethertypes) that higher-layer platforms cannot see.

Bidirectional Injection

Inject generated or modified frames directly up towards the Windows protocol stack (simulating inbound wire traffic) or downstream towards the network adapter (transmitting to the physical wire).

Standard & Optional Fast I/O

Provides reliable standard IOCTL queues (ReadPackets / SendPackets) alongside an optional shared-memory mechanism (FAST_IO_SECTION) for low-latency, high-throughput packet processing.

Why an NDIS Lightweight Filter?

Selecting the right Windows network packet interception architecture depends on your required network layer, development model, and deployment constraints.

Kernel vs. User Space

vs. Windows Filtering Platform (WFP)

While modern WFP provides Layer 2 MAC-layer filtering in addition to transport and socket layers, developing custom kernel callout drivers requires specialized Windows Driver Kit (WDK) development, complex kernel-mode debugging, and ongoing driver maintenance.

WinpkFilter provides a mature, pre-compiled NDIS 6 LWF driver. Applications can intercept, inspect, modify, and reinject network traffic through a straightforward user-mode API (C++, C#, Rust, Go), while Windows Packet Filter handles the low-level Windows networking integration.

Inline vs. Passive

vs. WinPcap & Npcap

WinPcap and Npcap are primarily designed for packet capture (promiscuous mode sniffing) and raw packet injection. They do not provide transparent, inline bidirectional packet modification or blocking for host network traffic.

WinpkFilter operates directly in the data path between protocol drivers and physical adapters, granting authoritative control to allow, drop, modify, or redirect every frame in real time.

Modern vs. Legacy

Modern NDIS LWF vs. Legacy NDIS Techniques

Earlier Windows releases required packet-filtering solutions to use techniques such as NDIS hooking or NDIS Intermediate (IM) drivers. NDIS hooking intercepted internal driver dispatch tables, making it undocumented, brittle, and prone to instability across service packs. NDIS Intermediate drivers were complex to install and manage, introduced significant packet processing overhead, and could cause binding conflicts with other network components.

Modern Windows supports the NDIS 6 Lightweight Filter (LWF) architecture for filtering in the network stack. WinpkFilter provides an NDIS 6 LWF implementation alongside its historical driver models; choose the appropriate package for your Windows version and architecture.

Engineered for Demanding Systems Software

Battle-tested since 2002 across enterprise firewalls, secure VPN gateways, industrial protocol analyzers, and commercial cybersecurity products.

Shared-Memory Fast I/O & Low Latency

Shared-memory packet sections between ndisrd.sys and user space reduce per-packet read IOCTL overhead. Throughput and CPU use depend on the application, packet sizes, hardware, and filtering configuration.

Bidirectional Packet Injection & Redirection

Transmit custom or modified packets in either direction: outbound to physical Ethernet/Wi-Fi media or inbound directly into the Windows TCP/IP stack. Transparently divert connections to local proxy sockets or encrypted tunnels.

System-Wide MTU Decrement & Jumbo Frames

A configurable system-wide MTU decrement helps account for tunnel encapsulation overhead. Jumbo-frame support is available in custom driver builds and requires matching user-mode packet-buffer capacity.

In-Kernel Rule Filtering & Buffer Pool

Programmatic rule engine inside ndisrd.sys allows developers to set pass, drop, or redirect rules directly in kernel space. Configurable intermediate buffer pool size optimizes memory allocation for bursty traffic.

Operating System & Hardware Support

WinpkFilter maintains a 20+ year lineage supporting modern enterprise Windows deployments while preserving legacy driver architectures.

Current Release (WinpkFilter 3.x)

NDIS 6.x LWF

Pre-compiled driver packages for supported Windows releases and CPU architectures:

Platform Installer Supported Windows Versions Architecture
ARM64 Installer Windows 11, Windows 10 ARM64
x64 Installer Windows 11, 10, 8.1, 8, 7, Vista* x64 (64-bit)
x86 Installer Windows 10, 8.1, 8, 7, Vista* x86 (32-bit)

Compatible with 64-bit Windows Server editions sharing the equivalent client kernel / NDIS version.
* Legacy Windows versions may require signing updates or an appropriate historical driver package. Verify the signing requirements and driver loading on your exact OS version.

Legacy Windows Driver Line

NDIS 3 – 5

Dedicated legacy driver builds maintained for older operating systems and industrial environments:

Operating System Driver Model Architectures
Windows Server 2003 / Windows XP NDIS 5.1 Intermediate (IM) Filter x86, x64
Windows 2000 / Windows NT 4.0 NDIS 4 Hooking Filter x86
Windows 95 / 98 / ME NDIS 3.1 Virtual Device Driver (VxD) x86

Archived driver packages for legacy system maintenance and long-term embedded deployment.

Supported Network Interfaces & Connection Media

Wired Ethernet (802.3; tested up to 10 GbE) Wi-Fi Wireless (802.11a/b/g/n/ac/ax) Mobile Broadband (3G/4G/5G PPP / WWAN) Dial-up / WAN (PPPoE, RAS, ISDN) Virtual Network Adapters (WinTun, WireGuard, TAP)

Applicability & Use Cases

Developers use Windows Packet Filter across a wide spectrum of network engineering, diagnostic, and security applications.

Firewalls & Packet Filtering

  • User-mode desktop firewalls without writing kernel driver code
  • Custom in-kernel filtering routines using the Source Code license
  • Application traffic isolation, domain blocking, and parental filters
  • Network protocol validation and malformed packet discarding

VPNs & Encrypted Tunnels

  • Custom WireGuard, IPsec, and SSL VPN client integration
  • Network packet encapsulation and tunneling (SSL, SSH, HTTP)
  • System-wide MTU decrementing to prevent tunnel packet fragmentation
  • Selective routing of application traffic through encrypted tunnels

Transparent Proxies & Redirection

  • Transparent SOCKS5 proxification of arbitrary Windows applications
  • Layer 2/3 packet redirection to local analysis or proxy sockets
  • SSL/TLS Server Name Indication (SNI) inspection and routing
  • Local DNS interception and DNS query redirection

Traffic Shaping & Analysis

  • Bandwidth metering, traffic shaping, and token bucket rate limiters
  • High-speed packet capture and PCAP file logging
  • Transparent software bridging between wired Ethernet and Wi-Fi
  • Industrial & SCADA raw Ethernet frame inspection

Real-World Software & Developer Samples

WinpkFilter powers enterprise networking software and provides maintained language bindings and representative sample applications.

Commercial Product

WireSock Secure Connect

High-performance WireGuard client for Windows. Uses Windows Packet Filter in both transparent and virtual adapter modes for application traffic routing and filtering. Transparent mode does not require a virtual network adapter.

Learn about WireSock Secure Connect →
Open Source Application

ProxiFyre SOCKS5 Client

Advanced SOCKS5 proxifier for Windows built on WinpkFilter. Transparently routes application TCP and UDP traffic through proxy instances without modifying client software.

Explore ProxiFyre →

Representative Open-Source Samples

View all 14+ samples on GitHub →
Sample Application Language Functionality Description Source
Capture Packet Filter C++ High-speed packet sniffer with pcap storage using Shared-Memory Fast I/O. GitHub
DNS Proxy Server C++ Transparently redirects DNS UDP traffic through a local proxy socket. GitHub
Static Packet Filter C++ Demonstrates in-kernel static packet filtering rules (pass, drop, or redirect to user space) using static filter tables. GitHub
SNI Inspector C++ Extracts TLS Server Name Indication (SNI) and HTTP Host headers in real time using Fast I/O. GitHub
ListAdapters C++ Enumerates TCP/IP bound network interfaces, MAC addresses, and adapter MTU. GitHub

Looking for Substantial Engineering Applications?

Explore dedicated architectural guides and source code for Internet Gateway (MFC NAT), WAN Emulator (latency injection), and Ethernet Bridge.

Explore Advanced Examples →

Licensing Options

Windows Packet Filter is free for personal or educational use, with transparent commercial licensing for software publishers.

Community

Personal / Educational

Free

Free for personal use, educational research, and non-profit organizations.

  • ✓ Complete SDK & User-Mode APIs
  • ✓ Official signed driver installer
  • ✓ Access to all sample applications
  • ✓ Community Forum Support
  • ✕ Commercial redistribution
  • ✕ Kernel driver source code
Download Free SDK
Software Publishers
Commercial

Binary License

$3,000 USD

For software publishers redistributing Windows Packet Filter binaries with one product.

  • ✓ Royalty-free binary redistribution with one product
  • ✓ Pre-compiled signed drivers (ndisrd.sys)
  • ✓ C++, C# (.NET), Rust, and Go client libraries
  • ✓ 1 Year of free updates & technical support
  • ✓ 1 custom driver build included
  • ✕ Kernel driver source code
Purchase Commercial License
Source Code

Source Code License

$9,000 USD

Complete driver and user-mode library source code for custom kernel development.

  • ✓ Full C/C++ driver source code (ndisrd.sys)
  • ✓ Full user-mode DLL source code (ndisapi.dll)
  • ✓ Custom in-kernel filtering routines
  • ✓ Independent compilation with the WDK
  • ✓ 1 custom driver build included (built to agreed configuration)
  • ✓ 1 Year of free updates & developer support
  • ✓ Royalty-free redistribution
License Source Code
Custom driver builds are supplied for customer deployment and signing; Microsoft signing and certification are the customer's responsibility. Read detailed licensing and signing terms →

Technical Support & Discussion

Have questions about NDIS 6 LWF behavior, packet injection edge cases, or multi-adapter configurations? Browse the support forum or ask directly.