数据包注入函数

标注驱动程序可以调用以下 WFP 函数,将已插入或修改的数据包数据注入 TCP/IP 堆栈。 下表列出了可从中注入数据的适用层以及可能的目标。

注入函数 适用的层 目标

FwpsInjectForwardAsync0

网络层

转发数据路径

FwpsInjectNetworkReceiveAsync0

网络层

接收数据路径

FwpsInjectNetworkSendAsync0

网络层

发送数据路径

FwpsInjectTransportReceiveAsync0

从传输层、数据报数据、ICMP 错误层或 ALE 层对数据进行数据包

接收数据路径

FwpsInjectTransportSendAsync0

从传输层、数据报数据、ICMP 错误层或 ALE 层对数据进行数据包

发送数据路径

FwpsStreamInjectAsync0

TCP 数据段

数据流

此外, FwpsQueryPacketInjectionState0 函数用于检查数据包数据的注入历史记录。

如果标注可以提供注入函数所需的所有信息,并且净缓冲区列表具有注入函数所需的格式,则启用跨层注入。 例如,标注可以在转发路径处捕获数据包,将其目标地址修改为本地计算机的目标地址,并调用 FwpsInjectTransportReceiveAsync0 将数据包重定向到本地计算机的 TCP/IP 堆栈中。

除了流 (TCP 数据) 注入,注入的传入数据包从堆栈和 WFP 层的“底部”重新进入,而注入的传出数据包从堆栈和 WFP 层的“顶部”重新进入。 例如,从传入数据报数据层注入的 UDP 数据包将重新进入堆栈并遍历网络层、传输层、ALE 接收层或接受层 (可选) ,并返回到数据报数据层。 从传出网络层注入的另一个 UDP 数据包将重新进入堆栈,并遍历 ALE (可选的) 、数据报数据和传输层,并返回到网络层。

FwpsInjectTransportReceiveAsync0 自动绕过重新注入的数据包的 IPsec 处理,因为它以前已经过 IPsec 验证。

WFP 标注驱动程序注入的数据包将重新指示到标注,但对数据包的修改导致其错过原始筛选条件的情况除外。 WFP 为标注提供 FwpsQueryPacketInjectionState0 函数,用于查询数据包是 (注入的,还是之前由标注) 注入的。 若要防止无限循环,标注应允许自注入数据包。

标注在修改 IP 数据包后,必须调整 IP 或传输层校验和/或两者。 标注可以将 UDP over IPv4 数据包的校验和设置为 0。 为了与传输层校验和卸载兼容,并相应地调整完整校验和与伪校验和计算,标注可以使用以下逻辑:

NDIS_TCP_IP_CHECKSUM_PACKET_INFO ChecksumInfo;
 ChecksumInfo.Value = 
 (ULONG) (ULONG_PTR)NET_BUFFER_LIST_INFO(
 NetBufferList,TcpIpChecksumNetBufferListInfo);

如果 ChecksumInfo.Transmit.NdisPacketTcpChecksum 为 TRUE,则会卸载 TCP 发送操作。 如果 ChecksumInfo.Transmit.NdisPacketUdpChecksum 为 TRUE,则 UDP 发送操作将被卸载。

在 Service Pack 1 的 Windows Vista (SP1) 和 Windows Server 2008 中,如果 inMetaValues-headerIncludeHeaderLength> 大于 0,则传出数据包是包含 IP 标头的 RAW 发送重新注入。 若要执行包含 Windows Vista SP1 和 Windows Server 2008 IP 标头的 RAW 发送重新注入,必须按 inMetaValues-headerIncludeHeaderLength> 中的量将克隆的数据包撤退,并在新扩展的空间上复制 inMetaValues-headerIncludeHeader>。 然后,将 FwpsInjectTransportSendAsync0 与数据包的净缓冲区列表一起使用,并将 FWPS_TRANSPORT_SEND_PARAMS0 参数设置为 NULL。 有关净缓冲区列表的撤退操作的详细信息,请参阅 撤退和高级操作

注意 对于原始发送操作,net 缓冲区列表必须仅包含单个 net 缓冲区。 如果净缓冲区列表包含多个净缓冲区,则必须将净缓冲区列表转换为一系列净缓冲区列表,并且该系列中的每个列表必须包含单个净缓冲区。 有关网络缓冲区列表管理的详细信息,请参阅 NET_BUFFER体系结构