使用第 2 层筛选
Windows 的 Windows 8 和更高版本中支持第2层筛选。
此 WFP 功能允许筛选第2层 MAC 标头的字段。 对于主机发送或接收的所有数据包,将根据每个数据包调用这些层。 在入站路径上的数据包重组之前以及出站路径上的数据包碎片后,将调用这些层。 可以从 (LWF) 驱动程序的 NDIS 轻型筛选器访问这些层。
注意
如果某个图层上没有相应的筛选器,则标注不应在该层上插入数据包。 NET_BUFFER_LIST结构的注入应与筛选器添加和移除进行协调,以便仅当相应层中存在筛选器时才执行注入。 此外,提供程序不应删除属于其他提供程序的筛选器。
本节包括下列主题:
注入 MAC 帧
回调驱动程序会调用 FwpsInjectMacReceiveAsync0 函数来 reinject 以前吸收的 MAC 帧 (或帧的克隆) 返回到它被截获的第2层入站数据路径,或在入站数据路径中注入一个发明的 mac 帧。
回调驱动程序会调用 FwpsInjectMacSendAsync0 函数来 reinject 以前吸收的 MAC 帧 (或帧的克隆) 返回到它被截获的第2层出站数据路径,或在出站数据路径中注入一个发明的 mac 帧。
NetBufferLists参数可以是NET_BUFFER_LIST链。 但是,完成函数可多次调用,完成段 (或链的单个 NET_BUFFER_LIST) 。
如果数据包与最初分类的筛选器匹配,则插入的帧可能会再次分类。 因此,与 IP 层的标注一样,第2层标注还必须通过调用 FwpsQueryPacketInjectionState0防止无限数据包检查。
此外,还必须在插入的层上安装标注。 否则,注入的 NET_BUFFER_LIST 将不会完成到完成函数中,并且 NET_BUFFER_LIST 将在堆栈中进一步。 在这种情况下,该行为是不确定的,因为 NDIS 会尝试将注入的 NET_BUFFER_LIST 传递到堆栈中的下一个组件。
NET_BUFFER_LIST状态成员包含堆栈注入的状态结果。 堆栈注入的状态结果是在 WFP 注入函数返回 STATUS_SUCCESS之后,堆栈置于 NET_BUFFER_LIST 的状态。 应使用 NT_SUCCESS 宏来检查 状态 成员中的堆栈注入状态。 如果 Status 值为 STATUS_SUCCESS,则注入成功,无需进一步的信息。 大于STATUS_SUCCESS的状态成员值意味着注入成功,但可能存在有关应考虑的注入的详细信息。 小于STATUS_SUCCESS的状态成员值意味着注入因状态成员中指定的原因而失败。
对链式网络缓冲区列表分类
默认情况下,标注驱动程序只能为网络缓冲区列表单独分类。 不过,如果标注驱动程序执行以下两项操作,则标注驱动程序可以对 NET_BUFFER_LIST 链进行分类以获得更好的性能:
- 指定FWPS_CALLOUT2结构的Flags成员中的FWP_CALLOUT_FLAG_ALLOW_L2_BATCH_CLASSIFY标志。
- 注册可对NET_BUFFER_LIST链进行分类的classifyFn2函数。
警告
但是,如果标注驱动程序设置了 FWP_CALLOUT_FLAG_ALLOW_L2_BATCH_CLASSIFY 标志,则它不能使用以下函数来修改 NET_BUFFER_LISTs。
- FwpsReferenceNetBufferList0
- FwpsDereferenceNetBufferList0
- FwpsAllocateCloneNetBufferList0
- FwpsFreeCloneNetBufferList0
设置此标志后, FwpsAllocateCloneNetBufferList0 将始终返回 INVALID_PARAMETER 错误。 这可能会意外导致第三方标注驱动程序无法管理 NET_BUFFER_LISTs 的引用计数,导致发送和接收操作停止。
WFP 第2层层和字段
虚拟交换机筛选的运行时筛选层标识符包括:
FWPS_LAYER_INBOUND_MAC_FRAME_ETHERNET
FWPS_LAYER_OUTBOUND_MAC_FRAME_ETHERNET
FWPS_LAYER_INBOUND_MAC_FRAME_NATIVE
FWPS_LAYER_OUTBOUND_MAC_FRAME_NATIVE
用于虚拟交换机筛选的数据字段标识符包括:
FWPS_FIELDS_INBOUND_MAC_FRAME_ETHERNET
FWPS_FIELDS_OUTBOUND_MAC_FRAME_ETHERNET