WFP Layer 2 Filtering について
こんにちは、紫陽花がきれいな季節になりましたね。WDK サポートチームのいわいだです。
Windows 8 から Layer 2 の MAC ヘッダー領域を Windows Filtering Platform のコールアウト ドライバーでフィルターできるようになっております。
今回は、その WFP Layer 2 Filtering についてご紹介します。
が、その前に一旦おさらいです。ネットワーク関連のフィルターには、
1. NDIS 中間ドライバー (NDIS IM)
2. NDIS フィルター ドライバー (NDIS Light Weight フィルター)
3. WFP コールアウト ドライバー
というようにそれぞれフィルター機能を有するドライバー インターフェイスが提供されています。
ざっくりと各種フィルターの役割や用途などについて説明すると、次のようになっています。このあたりについては、過去の Blog エントリ 「Windows の Network Driver」 にもありますのであわせてご参照ください。
図を見た感じだと、WFP コールアウト ドライバーが一番複雑そうですが、表中の左 (1) から右 (3) に行くほど、比較的軽量かつシンプルなドライバーの実装となります。
ちなみに、WFP Layer 2 コールアウト ドライバーは、 Layer 2 用の NDIS Light Weight フィルター (WfpLwfs.sys) から呼び出されているため、実態は NDIS フィルター ドライバーです。NDIS 部分の面倒なインターフェイス部分は WfpLwfs.sys が代わりに処理してくれています。
そして、Windows Filtering Platform では基本的にすべてのネットワーク レイヤーにおいて、トラフィックをモニタリングおよびインターセプトすることができます。
WFP コールアウト ドライバーが、どのレイヤーをフィルタリングするかは、 FwpmFilterAdd0 関数でフィルターオブジェクトを登録するときの Filtering Layer Identifiers で決定されます。たとえば、トランスポート層であれば FWPM_LAYER_INBOUND_TRANSPORT_V4 や FWPM_LAYER_INBOUND_TRANSPORT_V4 といった ID を指定します。
Windows 8 から追加された、Layer 2 フィルタリングは、その名の通り Layer 2 であるデータリンク層をフィルターできるもので、IEEE 802.3 Ethernet や IEEE 802.11 WLAN フレームなどをフィルターできます。
Layer 2 フィルタリングの場合には以下の ID を指定します。
FWPM_LAYER_INBOUND_MAC_FRAME_ETHERNET
FWPM_LAYER_OUTBOUND_MAC_FRAME_ETHERNET
FWPM_LAYER_INBOUND_MAC_FRAME_NATIVE
FWPM_LAYER_OUTBOUND_MAC_FRAME_NATIVE
FWPM_LAYER_xxx_FRAME_ETHERNET と FWPM_LAYER_xxx_MAC_FRAME_NATIVE の違いですが、有線 LAN、つまり 802.3 Ethernet の場合は特にありません。
一方、例えば 802.11 Wireless LAN などの場合、FWPM_LAYER_xxx_FRAME_ETHERNET を指定すると 802.11 WLAN フレームへの変換前(または後)の 802.3 Ethernet フレームをフィルタリングできます。それに対し、FWPM_LAYER_xxx_MAC_FRAME_NATIVE を指定すると、通信媒体に依存した 802.11 WLAN フレームをフィルタリングできます。
実際のところ Layer 2 のフィルタリングについては、NDIS Light Weight フィルターでもできますが、新たに作成を検討される場合は、複雑な NDIS に対する実装を省略できるため WFP の利用をお勧めします。
なお、サンプルコードについては、以前の Blog エントリ 「Windows Filtering Platform Sample をインストールする」で紹介されている WFPSampler が利用できますので、こちらもご参照ください。
<注意事項 >
WFP Layer 2 フィルターに関するドキュメント “Using Layer 2 Filtering” にて、チェインされた NET_BUFFER_LIST を扱いパフォーマンスを向上させるフラグ FWP_CALLOUT_FLAG_ALLOW_L2_BATCH_CLASSIFY が紹介されていますが、こちらを指定した場合、NET_BUFFER_LIST のクローンやリファレンスカウンタのインクリメント・デクリメントを行う次の関数が機能しません。
FwpsAllocateCloneNetBufferList0 FwpsReferenceNetBufferList0 FwpsDereferenceNetBufferList0
FwpsFreeCloneNetBufferList0
この現象については、前述の Using Layer 2 Filtering のドキュメント内の Classifying Chained Network Buffer Lists にある Warning にも記載がありますが、上記 4 つの関数を利用する場合は、 FWP_CALLOUT_FLAG_ALLOW_L2_BATCH_CLASSIFY フラグを設定しないようにします。
WDK サポートチーム 祝田 亮一