FwpsConstructIpHeaderForTransportPacket0 函数 (fwpsk.h)

通过标注调用 FwpsConstructIpHeaderForTransportPacket0 函数,以构造新的 IP 标头,或仅为一个净缓冲区重新生成预先存在的 IP 数据包标头。

注意FwpsConstructIpHeaderForTransportPacket0FwpsConstructIpHeaderForTransportPacket 的特定版本。 有关详细信息 ,请参阅 WFP Version-Independent 名称和面向 Windows 的特定版本
 

语法

NTSTATUS FwpsConstructIpHeaderForTransportPacket0(
  [in, out]      NET_BUFFER_LIST  *netBufferList,
                 ULONG            headerIncludeHeaderLength,
  [in]           ADDRESS_FAMILY   addressFamily,
  [in]           const UCHAR      *sourceAddress,
  [in]           const UCHAR      *remoteAddress,
  [in]           IPPROTO          nextProtocol,
  [in, optional] UINT64           endpointHandle,
  [in, optional] const WSACMSGHDR *controlData,
  [in]           ULONG            controlDataLength,
  [in]           UINT32           flags,
                 PVOID            reserved,
  [in, optional] IF_INDEX         interfaceIndex,
  [in, optional] IF_INDEX         subInterfaceIndex
);

参数

[in, out] netBufferList

指向 NET_BUFFER_LIST 结构的指针,该结构描述要为其构造或重新生成新 IP 标头的克隆传输层数据包数据。 若要构造新的 IP 标头,请在传输标头的开头找到克隆NET_BUFFER_LIST结构的偏移量。 若要重新生成预先存在的 IP 数据包标头,请在 IP 标头的开头找到偏移量。

headerIncludeHeaderLength

如果 NetBufferList 指向的NET_BUFFER_LIST结构已包含 IP 标头,则指示现有 IP 标头的总大小(以字节为单位) ((如果存在) )。 如果 NetBufferList 不包含 IP 标头, 则 headerIncludeHeaderSize 为零。 否则,此参数的值等于 的 ipHeaderSize 成员 FWPS_INCOMING_METADATA_VALUES0 传递给标注驱动程序的 分类Fn 标注函数的结构。 请注意,调用此函数时,将删除现有 IPv6 标头的扩展标头,尽管将保留 IPv4 选项。 有关详细信息,请参阅“备注”。

[in] addressFamily

以下地址系列之一:

AF_INET

IPv4 地址系列。

AF_INET6

IPv6 地址系列。

[in] sourceAddress

指向源 IP 地址的指针,该地址将成为要构造的 IP 标头的一部分。 对于 IPv4,地址为 4 个字节。 对于 IPv6,地址为 16 字节。 源地址字节始终按网络字节顺序排列。

[in] remoteAddress

指向缓冲区的指针,指定远程 IP 地址,该地址将成为要构造的 IP 标头的一部分。

缓冲区可以包含 IPv4 地址 (4 个字节) 或 IPv6 地址 (16 个字节) ,并且地址必须按网络字节顺序指定。 IP 版本必须与 addressFamily 参数匹配。

[in] nextProtocol

指定要构造的新 IP 标头的 IPPROTO 协议类型。 有关 IPPROTO 枚举的详细信息,请参阅 AF_INETAF_INET6

[in, optional] endpointHandle

一个可选句柄,指示数据包要注入到的发送数据路径中的堆栈传输终结点。 此终结点句柄通过 的 transportEndpointHandle 成员提供给标注 FWPS_INCOMING_METADATA_VALUES0 传递给标注驱动程序的 分类Fn 标注函数的结构。

[in, optional] controlData

指向缓冲区的可选指针,该缓冲区包含 WSASendMsg 函数指定的套接字控制数据,如Microsoft Windows SDK文档中所述。 有关 WSACMSGHDR 类型的信息,请参阅 CMSGHDR

如果存在,套接字控件数据将提供给具有 controlData 成员的标注 FWPS_INCOMING_METADATA_VALUES0 传递给标注驱动程序的 分类Fn 标注函数的结构。

如果套接字控件数据不为 NULL,则必须在 分类Fn 函数的标注驱动程序实现中对其进行深入复制,并且 controlData 缓冲区必须保持有效,直到调用注入完成函数。

[in] controlDataLength

controlData 参数的长度(以字节为单位)。

[in] flags

指定 NBL 是用于发送路径还是接收路径的标志。 flags 参数可以具有以下值:

含义
FWPS_CONSTRUCT_IPHEADER_FOR_SEND 设置后,此标志指定 NBL 适用于发送路径。
FWPS_CONSTRUCT_IPHEADER_FOR_RECEIVE 设置后,此标志指定 NBL 用于接收路径。

对于支持 USO 或 URO 的标注驱动程序,必须将此参数设置为以下值之一。 其他标注驱动程序可以将此参数设置为 。 这些标志仅在 Windows Server 2022 23H2 及更高版本上受支持。 在以前版本的 Windows 中,标注驱动程序必须始终将此参数设置为

reserved

保留。 标注驱动程序必须将此参数设置为 NULL

[in, optional] interfaceIndex

接收原始数据包数据的接口的索引。 标注驱动程序应使用接口索引的值,该索引作为传入数据值之一传递给此参数的 分类Fn 标注函数。 此参数是可选的,可以为零。

[in, optional] subInterfaceIndex

接收原始数据包数据的子接口的索引。 如果要将数据包注入到指示原始数据包的同一子接口中,标注驱动程序应使用子接口索引的值,该索引作为传入数据值之一传递给此参数的 分类Fn 标注函数。 此参数是可选的,可以为零。

返回值

FwpsConstructIpHeaderForTransportPacket0 函数返回以下 NTSTATUS 代码之一。

返回代码 说明
STATUS_SUCCESS
已成功构造新的 IP 标头。
其他状态代码
出现了错误。

注解

FwpsConstructIpHeaderForTransportPacket0 在 WFP 出站传输层 (FWPS_LAYER_OUTBOUND_TRANSPORT_Xxx) 克隆的净缓冲区列表为属于 net buffer 列表链的每个网络缓冲区构造一个新的标头。 此函数还可用于重新生成数据包的预先存在的 IP 标头,在这种情况下,net 缓冲区列表必须仅包含一个净缓冲区。

当尚未创建 IP 标头,但源 IP 地址或源端口必须从传输层修改时,此函数非常有用。 虽然通常可以等待数据包到达网络层之前执行此类修改,但在 IP 数据包到达网络层之前加密或数字签名的 IPsec 环境中无法执行此操作。

可以将源 IP 地址修改为另一个本地定义的 IP 地址或本地计算机上不存在的另一个地址。 然后,可以将修改后的数据包发送或注入到接收或转发数据路径中。

如果指定了非零 endpointHandle 参数,则会话状态 (与套接字关联的套接字选项) (如果有)将用于构造每个新的 IP 标头。 同样,如果使用 controlData 和 controlDataLength 参数指定了其他套接字选项,则这些选项将用于构造每个新的 IP 标头。

如果输入净缓冲区列表是从入站 WFP 传输层克隆的,或者它是由于原始发送操作而创建的,则网络缓冲区已包含 IP 标头。 在这种情况下,调用此函数时,IPv4 选项将保留在新的 IP 标头中,但 AH/ESP 标头和 IPv6 扩展标头将被删除。 由于 TCP/IP 堆栈在 IPsec 处理后保留 AH/ESP 标头,因此无法轻松地将已由 WFP 指示并由标注克隆的数据包注入到接收数据路径中。 因此,此函数可用于使用 FwpsInjectTransportReceiveAsync0 函数重新生成要注入到接收数据路径中的 IPsec 处理数据包。

对于包含标头的会话;例如,若要筛选从出站传输层原始套接字发送 (GRE) 流量 (IP 协议 47) ,请在调用 FwpsConstructIpHeaderForTransportPacket0 之前使用以下过程:

  1. 通过调用 克隆网络缓冲区列表 FwpsAllocateCloneNetBufferList0 函数。
  2. 如果分类Fn 函数的 inMetaValues 参数指向的 FWPS_INCOMING_METADATA_VALUES0 结构的 headerIncludeHeaderLength 成员大于零,则按该数量将克隆的净缓冲区列表撤退;例如,通过调用 NdisRetreatNetBufferListDataStart
  3. 将 FWPS_INCOMING_METADATA_VALUES0 的 headerIncludeHeader 成员指向的缓冲区复制到克隆的净缓冲区列表的新退退区域。 缓冲区的大小必须等于 headerIncludeHeaderLength 的值。
  4. 调用 FwpsConstructIpHeaderForTransportPacket0 ,其 NetBufferList 参数指向克隆的 net 缓冲区列表,并将 headerIncludeHeaderSize 参数设置为 headerIncludeHeaderLength 的值。
FwpsConstructIpHeaderForTransportPacket0 禁用大型发送卸载 (LSO) 和校验和卸载对生成的净缓冲区列表的支持。 针对 TCP、UDP 和 ICMP) (上层协议计算完整校验和。 重新构造 IP 标头时,会重新计算 IP 校验和。

要求

要求
最低受支持的客户端 从 Windows Server 2008 开始可用。
目标平台 通用
标头 fwpsk.h (包括 Fwpsk.h)
Library Fwpkclnt.lib
IRQL <= DISPATCH_LEVEL

另请参阅

AF_INET

AF_INET6

CMSGHDR

FWPS_INCOMING_METADATA_VALUES0 FwpsInjectTransportReceiveAsync0

NET_BUFFER_LIST

classifyFn