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_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


この現象については現在詳細を調査中ですが、現象を回避するためには前述の FWP_CALLOUT_FLAG_ALLOW_L2_BATCH_CLASSIFY フラグを設定しないことで回避できることがわかっています。


WDK サポートチーム 祝田 亮一

Skip to main content