このチュートリアルは、OMNeT++シミュレーション環境で書かれたINETフレームワーク、TCP/IPやインターネットプロトコルのシミュレーションモデルに習熟するためのものである。
このチュートリアルは、ARPTestシミュレーションに対して書かれている。このシミュレーションを実行するために、初めにOMNeT++を以下の手順でインストールする(以下では、ユーザ名がjikkenuserの場合を仮定する)。
次のアプリケーションが立ち上がっていればOKです。今日はこれらのウインドのみを利用します。
後方のウインドは、OMNeT++/Tkenvウインド(メインウインドウ)です。このウインドを終了するとプログラムがexitします。そのウインドの中の右側の大きなウインドウはシミュレーション実行時の(C++コードのev <<の出力)ログメッセージを表示します。左側は、モデルのオブジェクトを表示します。3行のステータスバーがその上にあります。更に、その上にツールバーアイコンがあります。
前側のウインドは、シミュレーションモデルを表示しています。このウインドをクローズしても、"Inspect network"ツールバーアイコンを押せば、それをオープンすることが出来ます。
ツールバーの "Run" ボタンをクリックして下さい。
最初に見るのは、ノード間で交換される"autoconf"とラベル付けされたメッセージです。これは、イーサネットモデル自動コンフィグレーション処理です。
その後、約1msシミュレーション時間後に、自動コンフィグレーションは終了し、ネットワーク動作のシミュレーションが開始します。このモデルのシナリオでは、時刻1sにクライアントコンピュータ(ラップトップ)がサーバにTCPコネクションの設定を開始し、大きなデータストリームを送信します。サーバはクライアントが送ったデータを送り返すだけです。
下位層のネットワークはイーサネットなので、クライアントはTCP SYNパケットを送信する前にデフォルトルーターのMACアドレスを学習するためにARP requestを実行します。その後、TCPコネクションが設定され、データ転送が始まる。その前に、ARPTestのアニメーションの使い方を学習します。アニメーション速度はウインドウの最上部にあるスライダを調節することにより速くしたり遅くしたり出来ます。
シミュレーションの終了は、赤い"STOP"アイコンをクリックします。
"Fast"アイコンはメッセージアニメーションを停止し、500ms毎にログを更新します(この500という値はSimulation Optionsダイアログを使って変更できます)。Optionsメニューはツールバーからもアクセス可能です。 "Express"アイコンは最速でシミュレーションを実行し、1000ms毎にログを更新します。Expressモードでは、赤い"STOP!"ボタンをクリックすることにより、シミュレーションを止めることが可能です。
メインウインドウの3番目のステータスバーにシミュレーションの速度が表示されます。Ev/secはCPUが1秒当り実行する平均イベント数です。この値は、CPUの速度とイベント毎の処理量(ソースコードのhandleMessage(cMessage *)関数を参照するとわかる)と実行モード(Run,Fast,Express)に依存します。
Simsec/secは(実世界の)1秒当りシミュレーションの中では何秒進むか(実世界の1秒とシミュレーションの中の1秒は異なる)を表している。 Ev/simsecはシミュレーションの中で1秒間に発生するイベントの平均を表している。Simsec/secはシミュレーションの実行時間を予測するのに便利である。Ev/simsecは実行モード(Run,Fast,Express)とモデルの特性とサイズに依存します。
Expessモードで実行すると、以下のダイアログが現れるでしょう:
"No more events"はシミュレーションが正常に終了したことを表しています。このARPTestの場合、クライアントは正常にTCPコネクションを終了し、その動作を終え、実行中のパケットやタイマがモデル中に無い状態に到達したことを表しています。
シミュレーションはいくつかの方法で終了します。"Simulation time limit reached -- simulation stopped"メッセージが現れた場合は、omnetpp.iniで指定したシミュレーション時間に達したため終了したことを表します。その他、予め設定したCPU時間に達した場合終了する"CPU time limit reached"メッセージや、モデル内の構成要素がendSimulation()関数をコールしたため終了する"Simulation stopped with endSimulation()"メッセージがあります(例えば、統計的に十分な量のデータが収集出来たことを検出した時点でこの関数はコールされます)。
シミュレーションはSimulateメニューの"Rebuild network"コマンドを使って再実行出来ます。
基本事項の説明を終えて、ARPTestモデルに戻ります。
以下のような表示を見た人は多いと思います:
(スクリーンショットのrouter1の周りの)赤いフレームは、次のイベントの位置を指している。この位置は、離散イベントシミュレーションのイベント処理アルゴリズムが管理している。
中を見るために、一つのノード(クライアント、サーバ、またはルータ)をダブルクリックする。
クライアントモデル(左の図)の主な構成要素は以下の通り:
3層より上はない点を除くと、ルータの内部も同様である。更にこれらの要素(TCPやUDP等)をダブルクリックしていくと、次のようなウインドが開く。
このウインドは、この要素がC++で実装されているため、更に分解することが出来ない(つまりシンプル・モジュールであり、複数のサブモジュールからなる合成(コンパウンド)モジュールではない)ことを表している。このウインドはモジュール内部を表示している。
ARPTestシミュレーションは、その中にTCP, IP, ARP, Ethernetを含んでいる点で非常に複雑である。この資料では、ARPに焦点を当てるが他のプロトコルを調べることも可能です。
GUI上で最初のARPの動作(時刻1sにARP requestが現れる)が始まるのは、イーサネットのautoconfigメッセージのやり取りが終わった後である。これらのやり取りを素早く通過するには、"Run until..."アイコンを使うとよい。
シミュレーションを再開始 (Simulate|Rebuild network)後、ツールバーの"Run until..."をクリックします。
autoconfigはおよそ1msシミュレーション時間で終了し、最初のARP requestがおよそ1sなので、Run untilダイアログには2msを入れれば良い。
OKをクリックした後、シミュレーションは直にautoconfig期間を通過する。すると、ラップトップアイコンの周りに赤いフレームが現れ、ステータスバーの再上位ラインにクライアントで起きる次のイベントが表示される。"scheduled-events"(メインウインドの左側)のオブジェクトツリーをオープンすると、イベントが一つだけあり、それがクライアントアプリケーション(client.tcpApp[0])で起きることがわかる。
クライアントをダブルクリックし、内部を表示します。更に、network layerをダブルクリックしその内部を表示します。メインウインドのツールバーの"Step"を押すとイベントが1つ実行されて停止します。すると、アプリケーションがTCPにコネクションをオープンするように要求します(緑色の丸)。続いて、"Step"を押すと、TCPはSYN(TCPコネクション要求)パケットをnetwork layerに送ります。更に"Step"を押すと、IPデータグラムはrouting Tableを参照してパケットの宛先インタフェースをeth0に決定します。さらに、宛先(192.168.0.1)のイーサネットのMACアドレスが不明であるためMACアドレスを取得する(この動作をARPアドレス解決と呼ぶ)ためにIPデータグラムはARPに送られます。
ここからARPが始まります。次のイベント番号が #94(メインウインドの再上位ステータスバーに表示されている)であることをノートすると良いでしょう。"Run until..."ダイアログを使って94を入れれば、直ぐにここに来ることが出来ます。
ここで、"Step"を押すと次のイベントが実行され、arpはARP requestを送信します。
ARPはレイヤ3アドレス(IPアドレス)をレイヤ2アドレス(イーサネットMACアドレス)に変換します。変換のために、ARPは参照テーブル(ARPキャッシュ)を利用します。ARPキャッシュには、IPアドレスとMACアドレスの対が登録されています。もしも、キャッシュにIPアドレスが登録されていなければ、ARPはARP Requestをブロードキャストして近くのホストやルータにそのIPアドレスに対するMACアドレスが何か尋ねます。これが、今シミュレーションで行われていることです。
ARP request(赤い丸)をダブルクリックすると、以下のようなウインドウが表示されます。
このウインドはARP requestのフィールドの値(source MAC address, destination MAC address, source IP address, destination IP address)を表示しています。source MAC addressとsource IP addressはクライアント(ラップトップ)のアドレスです。destination IP addressはサーバのアドレスです。知りたいのはdestination MAC address(サーバのMACアドレス)で、今は0に設定されています。
ARPアドレス解決が未解決の間は、IPデータグラムをどこかのバッファに置いておく必要があります。arpアイコンの隣にラベル"q:1"があります。"q:1"テキスト(arpアイコンではない)をダブルクリックすると、以下のようなウインドが開いてバッファリング中のIPデータグラムのキューが表示されます。
表示されたウインドのSYNの行を再度ダブルクリックすると、バッファリング中のIPデータグラムの中身(source IP address, transportProtocol等)を見ることが出来ます。ARP requestパケットの中身を見た時とだいたい同様な表示であるが、大きな違いは、今回は"Encapsulated message"がある点である。これは、カプセル化されたパケット、つまりTCPパケットのフィールドが含まれている点である。
arpアイコンの上に青い文字で"1 cache entries, send req:1 repl:0 fail:0"と書かれている。ここで、ARPキャッシュに何があるか見てみよう。
arpアイコンをダブルクリックすると、ウインドが開きます。次に、Contentsを表示します。
コンテンツには、送信したRequest数(numRequestsSent)、受信したReply数(NumRepliesSent)、ARP解決待ちIPデータグラム数(pendingQueue)等のいくつかのカウンタの他にarpキャッシュ(arpCache)があります。arpCacheの行をダブルクリックするとarpキャッシュの中身が表示されます。
初めに、キャッシュの中は期待通り:192.168.0.1未解決(192.168.0.1 ==> pending)。
次に、もしもC++に精通しているならば、arpキャッシュは標準STL mapで実装されていることに気付くであろう。mapのキーはclass IPAddressであり、その値は、struct
ARPCacheEntryである。
次のイベントでは、arpはrequestを処理する。イベント#105まで"Step"ボタンを押す。ここでrouter1のarpのモジュール出力ウインドを開くと、何が起きるかわかる。
"Step"ボタンを押す。すると、arpはARP requestを受信後、ソースIPアドレスとソースMACアドレスを自分のarpキャッシュに追加する。その後、ARP
requestに対して返答するか否かの判断処理が走る。宛先IPアドレスはrouter1のIPアドレスではない。しかし、proxy ARPがオンになっている(このことは、arpをダブルクリックすれば確認出来る)。proxy
ARPでは、もしもルータが宛先IPアドレスへの経路を知っているならば、自分のMACアドレスを設定してARP requestに返答しなければいけない。この一連の動作がここで起きたのである。
arpがARP requestパケットを処理している間、次のような赤く点滅した矢印が現れた。
この矢印は、proxy ARP処理の一部として、arpがアドレス192.168.0.1への経路があるか否か確認するためにrouting tableを参照したことを示している(申し少し正確に述べると、そのアドレスへの出力ポートをrouting tableに問い合し、その結果出力ポートが不明か否かでそのアドレスへの経路が分らない/分るが確認出来る)。C++コードでは、この動作に対してメッソドのダイレクト呼出しが使われている。つまり、arpモジュールのC++コードはrouting tableオブジェクト(class RoutingTable)のint outportNo(IPAddress)メソッドを引数192.168.0.1を使って呼び出している。シミュレーションGUIでこの要求を可視化したのはシミュレーション環境である。
arpはARP replyを返すので、結果は"経路が分る"である。ARP Replyパケットを開くことによっても確認出来る。赤い丸をダブルクリックする。
すると、arp replyのフィールドの値が表示される。ソースIPアドレスと宛先IPアドレスが入替っている。更に、ソースMACアドレスフィールドにはrouter1のeth[1]インタフェースのMACアドレスが設定されている。
数回"Step"ボタンを押すと、 ARP Replyはイーサネットを通過してクライアントのarpに到着する。
ARP reply処理の結果は次のスクリーンショットで見ることが出来る。router1のMACアドレスがarpキャッシュに追加されている。キャッシュエントリの"age=0"は必要である。なぜならば、このエントリがある時間(ここでは120 s)エントリのソースIPアドレスとMACアドレスを持つパケットを受信しないと、キャッシュから取除かれるためである。実際には、最近更新された時間が各エントリに格納されるが、表示する場合ageは現実的である。ようやく、TCP SYNセグメントを運ぶIPデータグラムがイーサネット上に送信する準備が出来た。
このデータグラムに取り付けられたcontrol infoを見れば、ARPを使って解決したMACアドレスが含まれていることが理解できるでしょう。
課題:
レポート提出期限:
2回の実験を1つのレポートとして提出する。2 回目の実験が終了してから1 週間後(つまり、次のテーマの情報工学実験IV が行われる日)の17:00までに、WingNet(学生用ポータルサイトBeNeFITの中の業務支援を選択)
を使って提出して下さい。また、レポートはWord を使って作成して下さい。
WingNet の選択画面(1 班の例)は以下の通り。
注意事項:
表紙:
————————–(表紙)—————————
情報工学実験IV
テーマ名: ネットワーク・シミュレーション
情報工学科3 年 組 班
s0xaxxxx 氏名_____
実施日平成 年 月 日、 月 日
提出日平成 年 月 日
—————————————————————
本文:
その他:
OMNeT++に関する質問は種田研究室(C82)へ。