メイン   モジュール   デー タ構造   ファイルリスト   データフィールド   グローバル   関連ページ   注意事項   English

NPF ドライバの内部マニュアル
[WinPcap の内部構造]



モジュール

NPF の構造と定義
NPF 関数

詳細

 

 このセクションではネットグループパケットフィルタ(NPF)の内部、いわゆるWinPcapのカーネル部分に関して記述しています。ノーマル ユーザーの方々は、その内部構造というよりはWinPcapの使い方の方に興味があるでしょう。したがって、このモジュール内に公開されている情報は主に WinPcap開発者と保守者、またはドライバがどのように動作するのかに深い興味を持っている方々向けです。とりわけこのセクションを有益に読み進めて 行くためには、OS、ネットワークとWin32カーネルプログラミング、デバイスドライバ開発に関しての十分な知識を必要とします。

 NPFは多くの仕事をこなすWinPcapのコンポーネントで、ネットワーク上を伝送するパケットを処理してキャプチャをエクスポートしたり、 ユーザーレベルでのパケットの注入や解析機能を保持しています。

 続く段落では、NPFとOS、それとその基本構造の相互作用についてを詳述して行きます。

NPF と NDIS

 Network Driver Interface Specification(NDIS:ネットワークドライバインターフェイス規格)はネットワークアダプタ(それを管理するドライバ)とプロトコルドラ イバ(例としてTCP/IPを実行する)の間の通信を定義する、標準規格です。NDISの主な目的は、プロトコルドライバが特定のアダプタ化特定の Win32OSを気にすることなくネットワーク上(LANかWAN)でパケットを送受することを可能にする、いわば「ラッパー(包装する)」のようなもの として動作することです。

 NDISは三つのタイプのネットワークアダプタをサポートします。

  1. ネットワークインターフェイスカード(NIC)やNICドライバ NIC ドライバは、NICとして言及されたネットワークインターフェイスカードを直接管理します。NICドライバはその下位エッジ(端)ではハードウェアと直接 インターフェイスを取り、上位エッジでは下位レイヤがネットワークにパケットを送出するインターフェイスを提供し、割り込み処理、NICのリセット、 NICの停止またドライバへの問合せ(クエリー)と動作条件を設定するインターフェイスを上位レイヤに提供します。NICドライバはミニポートないしは昔 からの(レガシーな)フルNICドライバです。
  2. 仲介(インターミディエイト)ドライバ 仲介ドライバは、プロトコルドライバのような上位レベルドライバとミニポートをインターフェイス接続します。上位レベルドライバにとって、仲介ドライバは ミニポートのように動作します。ミニポートにとっては、仲介ドライバはプロトコルドライバのように動作します。仲介プロトコルドライバは、階層化がシステ ムパフォーマンスにマイナス効果があるとしても、他の仲介ドライバの上に層を成します。仲介ドライバを構築する典型的な理由は、現存する昔からのレガシー プロトコルドライバと、プロトコルドライバには知られていない新たなメディアタイプのためにNICを管理するミニポートの間でメディア変換を実行するため です。例えば、仲介ドライバはLANプロトコルからATMプロトコルへメディアを変換できます。仲介ドライバはユーザーモードのアプリケーション間ではや り取りが出来ませんが、他のNDIS間でならばそれが出来ます。
  3. トラスポートドライバやプロトコルドライバ プロトコルドライバは一つか一つ以上のネットワークインターフェイスカード上でその動作を提供しながら、IPX/SPXやTCP/IPなどのネットワーク プロトコルスタックを実行します。プロトコルドライバはその上位エッジではアプリケーション層のクライアントを提供し、その下位エッジでは介在する NDISドライバや一つか一つ以上のNICドライバに接続します。

 NPFはプロトコルドライバとして実行されます。それはパフォーマンスという観点から言うとベストな選択とは言えませんが、完全な直接トラフィッ クへのアクセスと同様にMAC例やからの合理的な非依存性を可能にします。

 各種のWin32OSが異なるバージョンのNDISを保持していることに注目してください。NPFはWindows2000とその派生物 (WindowsXP)に準拠しているNDIS5と、他のWin32プラットフォームに準拠しているNDIS3です。

 次の図はNDISスタック内のNPFの位置を示しています。

ndis.gif

図1: NDIS内のNPF

 OSとの相互作用(インタラクション)は通常は非同期です。このことはドライバが、NPFにオペレーションの要求があったときにシステムから呼び 出されるコールバック関数のセットを提供する、ということを意味しています。NPFは全てのアプリケーションのI/Oオペレーションのためのコールバック 関数をエクスポートします。オープン、クローズ、リード、ライト、ioctl等です。

 同じようにNDISとの相互作用も非同期です。新たなパケットの到着といったようなイベントは、コールバック関数(この場合は packet_tap())を通してNPFに通知されます。更に、NICドライバとNDISの間の相互作用は、ノンブロッキング関数によって実行されま す。NPFがNDIS関数を呼び出す時、その呼び出しは即座に返されます。プロセスが終了すると、NDISは関数が終了したことを知らせるために特定の NPFコールバックを呼び出します。ドライバは、パケット送出、NICでのパラメータのセットや要求といった、ローレベルのオペレーションのためにコール バックをエクスポートします。

NPFの基本構造

 次の図は、NPFドライバの参考とWinPcapの基本構造を示しています。

 

npf.gif

図2: NPFデバイスドライバ

 NPFは種々のオペレーションが実行できます。キャプチャ、モニタリング、ディスクのダンプやパケットの注入です。続く節ではそれぞれのオペレー ションを手短に説明しています。

パケットキャプチャ

 NPFの最も重要なオペレーションはパケットのキャプチャです。キャプチャの途中で、ドライバはネットワークインターフェイスを使用してパケット を調べ、それらをユーザーレベルアプリケーションに原形を保ったまま送ります。

 キャプチャのプロセスは、二つの主な構成に依存します。

 ユーザーバッファサイズは非常に重要です。なぜならそれは、単一のシステムコールでカーネルスペースからユーザースペースへコピーされるデータの 最大量を決定するからです。一方で、シングルコールでコピーされるデータの最小量もまた極めて重要な事項です。この変数の大きな値を前にして、カーネルは ユーザーにデータをコピーする前にパケットの到着を待ちます。これは低いシステムコールの数、すなわち、スニファのようなアプリケーションのためのより良 いセッティングであるロープロセッサ処理を保証します。反対に小さな値は、アプリケーションの受け入れ準備が整うとすぐにカーネルはパケットをコピーす る、ということを意味しています。これはカーネルからの良い反応性を必要とするリアルタイムアプリケーション(ARPリダイレクターやブリッジなど)に、 非常に優れたものとなっています。この観点からすると、NPFはユーザーに、最善の効率性か最善の反応性か(または何でも介在物をはさんだ状況)を選ばせ るという、設定可能な動作を保持しているといえます。

 wpcapライブラリは、アプリケーションに転送される最小限のデータ量と、読み込みが失効した後のタイムアウトを設定するための両方に使用され る、幾つかのシステムコールを含んでいます。デフォルトでは、読み込みタイムアウトは1秒で、カーネルとアプリケーションの間にコピーされるデータの最小 量は16Kです。

パケット注入

 NPFはネットワークに直接パケットを書き込むことが出来ます。ユーザーレベルアプリケーションはデータを送るために、NPFデバイスファイル上 のWriteFile()システムコールを実行します。データはそのままの形でプロトコルへカプセル化されずにネットワークへ送られるので、アプリケー ションはそれぞれのパケットの各種ヘッダを構築する必要があります。アプリケーションは通常はFCSを生成する必要はありません。なぜなら、それはネット ワークアダプタハードウェアによって算出され、ネットワークへ送出する前にパケットの最後に自動的に添付されるからです。

 ノーマルの状態ではパケットのネットワークへの送出比率は、各パケットのシステムコールの必要性のためにそう高くはありません。この理由ゆえに、 一つ以上のシングルライトシステムコールと一緒にシングルパケットを送出するという見込みが追加されました。ユーザーレベルのアプリケーションが IOCTLコール(コード:pBIOCSWRITEREP)と共にセットされ、シングルパケットが何回も繰り返されます。例えば、この値が1000にセッ トされれば、ドライバデバイスファイル上のアプリケーションに書き込まれる全ての直接パケットは、1000回送出される、ということになります。この機能 は、高速なトラフィックテスト生成という目的のために使用されます。コンテキストスイッチのオーバーロード(過負荷)はもはや現れないので、パフォーマン スが如実に良くなります。

ネットワーキングモニタリング

 WinPcapは、ネットワークトラフィック上のシンプルな統計値を算出することの出来る、プログラマブルモニタリングモジュールを提供していま す。このモジュールの背後にある構想は、図2に示されています。統計値はアプリケーションにコピーされる必要なく収集され、それらは単純にモニタリングエ ンジンからの結果を受け取って表示しています。これによりキャプチャするときのオーバーヘッド、つまりメモリとCPUクロックのオーバーヘッドを大幅に減 らすことが可能になります。

 モニタリングエンジンは、カウンタに続く分類子で出来ています。パケットはNPFのフィルタリングエンジンを使用して分類されます。NPFのフィ ルタリングエンジンはトラフィックのサブセットを選択する、設定可能な方法を提供します。フィルタをパスしたデータは、パケット数といった変数やフィルタ によって受け取られたバイト料をキープして、それらを入ってくるパケットデータと一緒にアップデートするカウンタへと送られます。それらの変数は、ユー ザーによって構成できる一定の期間にユーザーレベルのアプリケーションへと回されます。カーネル、ユーザーレベルで割り振られたバッファはありません。

ディスクへのダンプ

 ディスクへのダンプ機能は、カーネルモードからディスクへ直接ネットワークデータを保存するのに使用されます。

npf_dump.gif

図3:カーネルレベルダンプとパケットキャプチャの対比

 従来のシステムでは、ディスクに保存されるパケットにカバーされたパスは、図3中の黒い矢印の通りに進みます。全てのパケットが数回コピーされ、 通常は四つのバッファに割り振られます。キャプチャドライブの一つ、キャプチャデータを保存するアプリケーションの一つ、ファイルに書き込むアプリケー ションで使われるstdioの一つ、そして最後にファイルシステムの一つです。

 NPFのカーネルレベルのトラフィックロギング機能が有効にされると、キャプチャドライバは直接ファイルシステムのアドレスを取るので、パケット にカバーされたパスは赤い点線に矢印の通りに進みます。二つのバッファと一回のコピーだけが必要なので、システムコールの回数が大きく減って、パフォーマ ンスは大幅に向上します。

 この実行は、libpcapフォーマットで幅広く使われているディスクにダンプします。またそれは、ディスクへと送られるパケットを選択するため に、ダンプするプロセスの前にトラフィックをフィルタする可能性をも与えます。

参考文献

 NPFの構造とそのフィルタリングエンジンは、BSDパケットフィルタ(BPF)のうちの一つから派生します。もしこれらの項目に興味のある場合 は以下の文献を参考にして下さい。

- S. McCanne and V. Jacobson, The BSD Packet Filter: A New Architecture for User-level Packet Capture. Proceedings of the 1993 Winter USENIX Technical Conference (San Diego, CA, Jan. 1993), USENIX. 

- A. Begel, S. McCanne, S.L.Graham, BPF+: Exploiting Global Data-flow Optimization in a Generalized Packet Filter Architecture, Proceedings of ACM SIGCOMM '99, pages 123-134, Conference on Applications, technologies, architectures, and protocols for computer communications, August 30 - September 3, 1999, Cambridge, USA

注意書き

 本マニュアルに記されているコードは、NPFのWindows NTxバージョンのものです。Windows9xのコードはそれに似通ってはいますが、比較的効率的ではないこととカーネルモードダンプのような高機能が 欠落しています。

 


documentation. Copyright (c) 2002-2003 Politecnico di Torino.
2005 translated by Telebusiness,Inc.
 All rights reserved.