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」 にもありますのであわせてご参照ください。​

種類 1. NDIS 中間ドライバー 2. NDIS フィルター ドライバー 3. WFP コールアウト ドライバー
役割/用途 Media Type の異なるネットワーク スタックの接続 1つのプロトコルから複数の NIC への送受信(ブリッジ機能など) プロトコルドライバーとミニポートドライバーの間のフィルターモジュールプロトコルの種類は問わない TCP/IP ベースのパケット フィルタリングパケットの拒否、許可、書き換え、ロギングなど

 

図を見た感じだと、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_V4FWPM_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_ETHERNETFWPM_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 サポートチーム 祝田 亮一