パケット挿入関数
コールアウト ドライバーは、次の WFP 関数を呼び出して、保留中または変更されたパケット データを TCP/IP スタックに挿入できます。 次の表に、データを挿入できる適用可能なレイヤーと、考えられる宛先を示します。
挿入関数 | 適用可能なレイヤー | 宛先 |
---|---|---|
ネットワーク層 |
転送データ パス |
|
ネットワーク層 |
受信データ パス |
|
ネットワーク層 |
送信データ パス |
|
トランスポート、データグラム データ、ICMP エラー、または ALE レイヤーからのパケット データ |
受信データ パス |
|
トランスポート、データグラム データ、ICMP エラー、または ALE レイヤーからのパケット データ |
送信データ パス |
|
TCP データ セグメント |
データ ストリーム |
さらに、FwpsQueryPacketInjectionState0 関数は、パケット データの挿入履歴を検査するために使用されます。
クロスレイヤー挿入は、コールアウトが挿入関数に必要なすべての必要な情報を提供でき、ネット バッファー リストが挿入関数で予期される形式を持つ場合に有効になります。 たとえば、コールアウトでは、転送パスでパケットをキャプチャし、その宛先アドレスをローカル コンピューターのアドレスに変更し、FwpsInjectTransportReceiveAsync0 を呼び出して、パケットをローカル コンピューターの TCP/IP スタックにリダイレクトできます。
ストリーム (TCP データ) 挿入を除き、挿入された受信パケットはスタックと WFP レイヤーの「下部」から再入力され、挿入された送信パケットはスタックレイヤーと WFP レイヤーの「上部」から再入力されます。 たとえば、受信データグラム データ層から挿入された UDP パケットは、スタックに再入し、ネットワーク層、トランスポート層、ALE 受信層または受け入れ層 (省略可能) を走査し、データグラム データ層に戻ります。 送信ネットワーク層から挿入された別の UDP パケットは、スタックに再入し、ALE (省略可能)、データグラム データ、およびトランスポート層を走査し、ネットワーク レイヤーに戻ります。
FwpsInjectTransportReceiveAsync0 は、以前に IPsec 検証を行っていたため、再挿入されたパケットの IPsec 処理を自動的にバイパスします。
WFP コールアウト ドライバーによって挿入されたパケットは、パケットの変更によって元のフィルター条件を満たさなくなる場合を除き、コールアウトに再び示されます。 WFP は、コールアウトによってパケットが挿入された (または以前に挿入された) かどうかを照会するコールアウト用の FwpsQueryPacketInjectionState0 関数を提供します。 無限ループを防ぐには、コールアウトで自己挿入パケットを許可する必要があります。
コールアウトでは、IP パケットを変更した後、IP またはトランスポート層チェックサムまたは両方を調整する必要があります。 IPv4 パケット経由の UDP では、コールアウトで チェックサム を 0 に設定できます。 トランスポート層チェックサム オフロードと互換性があり、それに応じて完全なチェックサムと擬似チェックサムの計算を調整するには、コールアウトで次のロジックを使用できます。
NDIS_TCP_IP_CHECKSUM_PACKET_INFO ChecksumInfo;
ChecksumInfo.Value =
(ULONG) (ULONG_PTR)NET_BUFFER_LIST_INFO(
NetBufferList,TcpIpChecksumNetBufferListInfo);
If ChecksumInfo.Transmit.NdisPacketTcpChecksum が TRUE の場合、TCP 送信操作はオフロードされます。 If ChecksumInfo.Transmit.NdisPacketUdpChecksum が TRUE の場合、UDP 送信操作はオフロードされます。
Windows Vista Service Pack 1 (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 に設定したままにしておきます。 ネット バッファー リストの退避操作の詳細については、「退避操作と事前操作」を参照してください。
注: 生の送信操作の場合、ネット バッファー リストには 1 つのネット バッファーのみを含める必要があります。 ネット バッファー リストに複数のネット バッファーが含まれている場合は、ネット バッファー リストを一連のネット バッファー リストに変換する必要があり、各シリーズ内に 1 つのネット バッファーが含まれている必要があります。 ネット バッファー リスト管理の詳細については、「NET_BUFFER アーキテクチャ」を参照してください。