WFP Layers: Where to Hook In
WFP is layered to reflect the OSI model:
| Layer | Description | Common Use Case |
|---|---|---|
| Application Layer | App-specific, DNS, HTTP, SMB | Filtering browser requests |
| Transport Layer | TCP/UDP connections and data streams | Blocking outbound port 443 |
| Network Layer | IP packets | IP blacklisting, routing |
| Link/NDIS Layer | Raw packets, before TCP/IP | Custom VPNs, lowest-level filtering |
WFP exposes dozens of filtering points called filtering layers – each associated with a part of the network stack.
Some key ones:
| Layer Name | Trigger Event |
|---|---|
FWPM_LAYER_ALE_AUTH_CONNECT_V4 | App attempts outbound connection |
FWPM_LAYER_STREAM_V4 | TCP stream data becomes available |
FWPM_LAYER_DATAGRAM_DATA_V4 | UDP data |
FWPM_LAYER_INBOUND_TRANSPORT_V4 | Incoming TCP/UDP before app sees it |
FWPM_LAYER_OUTBOUND_TRANSPORT_V4 | Outbound traffic before it hits the wire |
Each filter you install must bind to a specific layer. Choosing the wrong one = no filtering or delayed detection.
Filters, Callouts, and Actions
Filters
A filter in WFP is like a rule:
"If traffic matches these conditions, then apply this action."
Each filter:
- Has a layer (e.g.,
FWPM_LAYER_ALE_AUTH_CONNECT_V4) - Lives inside a sublayer
- Can match on:
- Protocol (TCP/UDP)
- IP addresses
- Ports
- Application (path or SID)
- Packet size, direction, etc.
Example (in plain English):
Block all outbound TCP connections on port 25 unless from
smtp.exe.
Actions
Actions determine what happens when a filter is matched:
| Action Type | What It Does |
|---|---|
FWP_ACTION_BLOCK | Drops the packet or connection |
FWP_ACTION_PERMIT | Allows it through |
FWP_ACTION_CALLOUT_TERMINATING | Invokes your custom logic (callout) |
You use callouts when you want to inspect, modify, log, or analyze data in detail.
Callouts
A callout is a kernel-mode function (registered with FwpsCalloutRegister) that gives you direct access to the packet or stream data.
Use a callout if:
- You need to scan content (DLP)
- You want to redirect traffic (VPN/tunneling)
- You want full control over permit/block decision
Filters can exists without callouts, but callouts cannot exist without filters.
Sublayers and Prioritization
Filters are grouped into sublayers, which:
- Organize filters by purpose or ownership
- Assign priority (lower number = higher priority)
- Enable/disable groups of filters together
You should:
- Create a sublayer for your product (e.g.,
"MyDLP_Sublayer") - Use priorities to ensure your filters run before/after Windows Firewall or other apps
Example:
FWPM_SUBLAYER mySublayer = {0};
mySublayer.subLayerKey = MY_SUBLAYER_GUID;
mySublayer.displayData.name = L"My DLP Sublayer";
mySublayer.flags = 0;
mySublayer.weight = FWP_EMPTY; // dynamic priority
FwpmSubLayerAdd(engineHandle, &mySublayer, NULL);
Traffic Flow Through WFP
Let's say an app tries to open a TCP connection:
1. App calls connect() → triggers FWPM_LAYER_ALE_AUTH_CONNECT_V4
2. Filter checks if destination IP/port is allowed
3. If permitted, TCP handshake begins
4. Data is sent → triggers FWPM_LAYER_STREAM_V4
5. Your callout inspects content of stream
6. WFP returns permit/block result
This layered processing allows:
- Early rejection (e.g., block before handshake)
- Deep content scanning (e.g., DLP/antivirus)
- Real-time analytics (e.g., IDS/monitoring)
Choosing the Right Layer
| Goal | Recommended Layer |
|---|---|
| Block outbound connections | ALE_AUTH_CONNECT_V4 |
| Scan HTTP/SMTP content | STREAM_V4 or DATAGRAM_DATA_V4 |
| Monitor all raw IP traffic | INBOUND_TRANSPORT_V4 |
| Build a transparent proxy | STREAM_V4 + injection |
Choosing the wrong layer is the most common WFP mistake.

Join the discussion
Sign in with your account to post comments, reply to others, and participate in the conversation.
Login to Comment