使用第 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 链进行分类以获得更好的性能:

警告

但是,如果标注驱动程序设置了 FWP_CALLOUT_FLAG_ALLOW_L2_BATCH_CLASSIFY 标志,则它不能使用以下函数来修改 NET_BUFFER_LISTs。

设置此标志后, 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

FWPS_FIELDS_INBOUND_MAC_FRAME_NATIVE

FWPS_FIELDS_OUTBOUND_MAC_FRAME_NATIVE