Solaris で SoftEther もどきを動かそう/番外編 - Windows 版 -
if ($preview) { ?>
print($vars["preview"]); ?>
} ?>
WYSIWYGԽǤΤϡInternet ExplorerMozillaϥ֥饦(Firefoxʤ)ΤߤǤ
̾Խ
#norelated<br/><br/> <h2 id="">Solaris で SoftEther もどきを動かそう/番外編 - Windows 版 -</h2> <h2 id="">概要 [#y0b8536d]</h2> <h3 id="">SteVPN 〜簡易VPNアプリケーション〜 [#z89460a8]</h3> SteVPN は離れたのネットワーク上にいる2つの Windows マシンをあたかも同一のネットワークにつながっているように見せる VPN アプリケーションです。Windows のブリッジ接続機能を使えば片方 Windows マシンにつながっている実際のネットワークに仮想的に接続することができます。<br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/net_config_sample.GIF)<br/><br/> もともとは「Solaris で SoftEther もどきを動かそう」 で作ったプログラムの Windows 版です。<br /> Windows マシン同士だけでも VPN が組めるように、Windows 上で動作する「仮想 NIC ドライバ」、「仮想 NIC デーモン」、「仮想ハブ」があります。もちろん Solaris版の SteVPN とも接続できます。<br/><br/> <h2 id="">目次 [#s442aa31]</h2> #contents<br/><br/> <h2 id="">ご注意 [#d1f3986a]</h2> ここで紹介しているプログラムは、カーネルモジュールを含んでいます。そのため、プログラム上に問題があった場合(可能性大)にはクラッシュもしくはハング等、システムに重大な障害を引き起こす可能性があります。以下のプログラムはテストプログラムで、十分な検証を行ってはいません。したがってあくまで個人の検証ためにお使いいただき、重要なシステム上では動作させないでください。<br/><br/> また、ご利用方法によってはファイアーウォールで守られたローカルネットワークを外部へ共有することができてしまいます。本プログラムはあくまで実験的な目的のものであり、ユーザ認証や暗号化といったセキュリティの機能をまったく有しておりませんので、インターネット上に意図せず機密情報が漏れてしまう恐れがあります。もしご使用になられる場合には、この点を十分考慮の上、かならず自分の管理下にあるネットワークでご使用ください。くどいようですが、ご利用は自己責任でお願いします。<br/><br/> <h2 id="">ダウンロード [#p74efb04]</h2> <h4 id="">インストーラ [#l401e922]</h4> Windows のインストールファイルはこちらからダウンロードできます。<br/><br/> インストーラ:&#160;<a href="" rel="nofollow">https://github.com/downloads/kaizawa/vpn-ste-win/SteVPN_setup-1.1.2.msi</a>&#160;<br/><br/> <h4 id="">ソースファイル [#c62ce995]</h4> ソースファイルはこちらからダウンロードできます。<br/><br/> ソースファイル: <a href="" rel="nofollow">https://github.com/kaizawa/vpn-ste-win/zipball/master</a> (<span style="font-weight: bold;">実行可能ファイルは含まれておりません。各自でコンパイルしていただく必要があります。</span>)<br/><br/> zip ファイルに含まれるファイル<br/><br/> <div class="ie5"><table class="style_table" cellspacing="1" border="0"><tbody><tr><td class="style_td" colspan="2">sys ディレクトリ</td></tr><tr><td class="style_td">sources</td><td class="style_td">Sources ファイル</td></tr><tr><td class="style_td">ste.c</td><td class="style_td">仮想 NIC ドライバ ste.sys のメインモジュールのソースファイル。<br />NDIS から呼び出されるのミニポートドライバのエントリポイントが含まれおり、またエントリポイントの登録もこの中で行われる。</td></tr><tr><td class="style_td">ste_local.c</td><td class="style_td">Ste ドライバが利用する内部関数が含まれているソースファイル。((Macアドレスについて: 仮想 NIC の MAC アドレスは以前はハードコードされていましたが、現在はインストール時に動的に割り当てるようにしています。)) 2006/05/05 更新</td></tr><tr><td class="style_td">netste.inf</td><td class="style_td">ドライバのインストールの為の INF ファイル</td></tr><tr><td class="style_td" colspan="2">inc ディレクトリ</td></tr><tr><td class="style_td">ste.h</td><td class="style_td">Ste ドライバ用のヘッダファイル。構造体、定数、関数のプロトタイプを含む。</td></tr><tr><td class="style_td">sted.h</td><td class="style_td">Sted.exe 仮想 NIC デーモン用のヘッダファイル。Solaris 版と共通。</td></tr><tr><td class="style_td">sted_win.h</td><td class="style_td">Windows 版仮想 NIC デーモン用ヘッダファイル</td></tr><tr><td class="style_td">getopt_win.h</td><td class="style_td">擬似 getopt 用ヘッダファイル</td></tr><tr><td class="style_td" colspan="2">exe/sted ディレクトリ</td></tr><tr><td class="style_td">sources</td><td class="style_td">Sources ファイル</td></tr><tr><td class="style_td">sted.c</td><td class="style_td">仮想 NIC デーモン sted.exe のメインソースファイル。</td></tr><tr><td class="style_td">sted_socket.c</td><td class="style_td">仮想 NIC デーモンの Socket 通信用ソースファイル。Solaris 版と共通。</td></tr><tr><td class="style_td">getopt_win.c</td><td class="style_td">Solaris とのコード互換のための擬似 getopt() 関数のソースファイル。</td></tr><tr><td class="style_td" colspan="2">exe/stehub ディレクトリ</td></tr><tr><td class="style_td">sources</td><td class="style_td">Sources ファイル</td></tr><tr><td class="style_td">stehub.c</td><td class="style_td">仮想ハブ stehub.exe のメインソースファイル。Solaris 版と共通。</td></tr><tr><td class="style_td">getopt_win.c</td><td class="style_td">Solaris とのコード互換のための擬似 getopt() 関数のソースファイル。</td></tr></tbody></table></div> 各ソースコードは以下ページで参照することもできます。<br/><br/> <blockquote>http://github.com/kaizawa/vpn-ste-win</blockquote> 各ファイルのコメントの文字コードは <span style="font-weight: bold;">UTF-8</span> です。<br/><br/> <h2 id="">インストール [#hbd5b7c4]</h2> 以下の手順は Windows 7 での操作をベースにしています。<br/><br/> <h3 id="">インストールファイルの実行 [#b4b28703]</h3> ダウンロードしたインストールファイルを実行します。<br/><br/> キュリティ警告がでますがよろしければ「実行」します<br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/install-security-alert.png)<br/><br/> インストールが進みます<br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/installer-installing.png)<br/><br/> 今度はドライバに対するセキュリティの警告がでますが、こちらもよければ「このドライバーソフトウェアをインストールします」をクリックして先に進めます。<br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/install-driver-security-alert.png)<br/><br/> 最後にデバイスを接続するよう即すダイアログが出てきてインストール終了です。<br/><br/> もちろん ste ドライバは実ハードウェアの存在しない擬似デバイスドライバなのでハードウェアを接続することはできません。<br /><br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/install-finish.png)<br/><br/> <h3 id="">ドライバのインストール [#qbfe1556]</h3> インストーラの実行で実行ファイルとドライバを Windows にコピーすることはできましたが、まだドライバは利用可能になっていません。((本当はインストーラから自動的にドライバのインストールもさせたかったのですが、非Plug And Play なソフトウェアドライバを自動インストールさせる方法がわかりませんでした。要件等です))以下の手順に従ってドライバを Windows にインストールします。<br/><br/> コントロールパネルからデバイスマネージャを開き「操作」→「レガシーハードウェアの追加」を選んでハードウェアの追加ウィザードを起動します。((Windows XP の場合はコントロールパネルから「ハードウェアの追加」で起動できます。))<br/><br/> もしくはスタートメニューの「プログラムとファイルの検索」より「hdwwiz.exe」と入力しても同じウィザードが始まります。<br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/start-wizard.png)<br /> 追加するハードウェアの選択方法をきかれますので「一覧から選択したハードウェアをインストールする」を選びます。<br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/how-to-install.png)<br/><br/> ハードウェアの選択画面では「ネットワークアダプタ」を選んでください。<br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/select-network-driver.png)<br/><br/> ネットワークアダプタの選択画面ではもし「SteVPN Virtual NIC」と出ていればそれを選択して継ぎへ行きます。もしなければ「ディスクを使用」をクリックし「製造元ファイルのコピー元」を C:\Program Files\SteVPN\driver にして「OK」をクリックした後「SteVPN Virtual NIC」を選択して次へ行きます。<br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/select-adapter.png)<br /><br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/select-copy-source.png)<br/><br/> インストールが無事に完了すると以下の画面が現れますので「完了」をクリックします。<br/><br/> #ref(http://www.whiteboard.ne.jp/~admin2/pict/finish.png)<br /> 以上で新しい仮想ネットワークアダプタが追加されドライバもインストールされました。<br/><br/> <h3 id="">アンインストール [#rbce6d9f]</h3> アンインストールは通常通り「プログラムと機能」からアンインストールできます。<br /> SteVPN をアンインストールすると stehub, sted デーモンプログラムと同時にドライバーもアンインストールされます。<br/><br/> <h2 id="">各プログラムの概要 [#l100f047]</h2> プログラムの概要は Solaris 版と同様です。NIC や HUB をソフトウェアで仮想化することにより、レイヤ2での VPN を実現しており、それらは以下の3つのプログラムで構成されます。<br/><br/> <div class="ie5"><table class="style_table" cellspacing="1" border="0"><tbody><tr><td class="style_td">ste.sys</td><td class="style_td">デバイスドライバ</td><td class="style_td">仮想 NIC デバイスドライバ。物理 NIC が存在するドライバように振る舞い、上位プロトコルからのメッセージを Ethernet フレームにして仮想 NIC デーモンに転送する</td></tr><tr><td class="style_td">sted.exe</td><td class="style_td">ユーザモードプログラム<br />(コンソールプログラム/Windows サービス)</td><td class="style_td">仮想 NIC デーモン。仮想 NIC ドライバから受け取った Ethernet フレームを TCP socket を使って仮想ハブに転送する。</td></tr><tr><td class="style_td">stehub.exe</td><td class="style_td">ユーザモードプログラム<br />(コンソールプログラム)</td><td class="style_td">仮想ハブ。任意の TCP ポート で仮想 NIC デーモンからの接続を待ち受けるサーバプログラムで、一つの仮想 NIC デーモンからのパケットを別の仮想 NIC デーモンに転送する。</td></tr></tbody></table></div> もちろんコードは違いますが、各プログラムの基本的な方針についても Solaris 版と同様です。<br/><br/> <ul class="list1 list-indent1"><li>カーネルモードで動作する仮想 NIC のデバイスドライバを動作させる。</li> <li>仮想 NIC ドライバは、 アプリケーションからは実在の NIC が存在するように振舞う。</li> <li>仮想ハブと仮想 NIC との通信はユーザモードのデーモン(Windows サービス)で行い、通信には OS のプロトコルスタックを利用する。</li> <li>仮想ハブと仮想 NIC デーモンとの通信には TCP を使う。</li></ul> <h2 id="">使い方 [#xc42cf82]</h2> 仮想 NIC ドライバ、仮想 NIC デーモン、仮想ハブデーモンの使い方をご説明します。<br/><br/> <h3 id="">仮想 NIC ドライバ [#x408f378]</h3> 仮想 NIC ドライバは実 NIC があるかのように振舞いますので、IP アドレス等の設定は、通常の NIC と同様に「ネットワーク接続」ウィンドウから可能です。<br/><br/> <ol class="list1 list-indent1"><li>「スタート」->「設定」->「ネットワーク接続」</li> <li>「Ste Virtual NIC」を選択し、左クリックのメニューから「プロパティ(R)」を選択</li> <li>「インターネットプロトコル(TCP/IP)」を選択し、「プロパティ(R)」をクリック</li> <li>「次のインターネットアドレスを使う」を選択し、「IP アドレス」、「サブネットマスク」に仮想ネットワークで使うアドレス、サブネットマスクを入力</li></ol> 複数の仮想 NIC ドライバをインストールすると(つまり上述のインストール作業を複数回行うと)、「ネットワーク接続」ウィンドウに「Ste Virtual NIC #2」「Ste Virtual NIC #3」などが増えていきますが、この #2 や、#3 と、Ste.sys 仮想 NIC ドライバが管理しているインスタンス番号とに関連性は無いので注意してください。仮想 NIC ドライバのインスタンス番号は 0 から始まり、インスタンスが追加されるたびに(SteMiniportinitialize() が呼ばれるたびに)0, 1, 2 ... のように増えていきます。<br/><br/> <h3 id="">仮想ハブ(プログラム名 stehub.exe) [#x11092e7]</h3> 仮想 NIC デーモンからの接続を待ち受けるポートを -p オプションで指定します。オプションを指定しない場合にはデフォルトで 80 が使われます。<br /> 通常 -I と -U というオプションが追加されています。Windows 版には Solaris 版には無い -I と -U というオプションが追加されています。-I では stehub.exe を Windows サービスとして登録します。また -U を使うと、Windows サービスの登録を解除します。<br/><br/> <pre>Usage: stehub.exe&#160;[ -I | -U ] [ -p port] [-d level] -p port : Port nubmer -d level : Debug level[0-1]&#160; -I : Install Service -U : Uninstall Service</pre> <pre>C:\winvpn> stehub -p 8888</pre> 最初の起動時に起動後 Windows ファイアーウォールからの警告画面が現れます。この画面で外部からこのシステムへのTCP接続を許可する設定を行うことができます。セキュリティ上問題なければ「パブリックネットワーク」にチェックを入れて「アクセスを許可する」をクリックします。<br /> &ref(http://www.whiteboard.ne.jp/~admin2/pict/firewall-alert.png);<br /><br/><br/> #br なお Windows サービスとして登録した場合、-p、-d&#160; などのオプションはコントロールパネルの「サービス」にて「開始パラメータ」として指定します。<br /> &ref(http://www.whiteboard.ne.jp/~admin2/pict/service-stehub-detail.png);<br/><br/> <h3 id="">仮想 NIC デーモン(プログラム名 sted.exe) [#x8785cfa]</h3> 起動時にste デバイスのインスタンス番号と、接続する仮想ハブのホスト名、ポート番号、また必要であればプロキシサーバ名、ポート番号を指定します。なにも指定されなかった場合、デフォルトのインスタンス番号は 0、デフォルトで接続するホスト名は localhost で、接続するポート番号は 80です。<br /> 「仮想ハブ」、「プロキシサーバ」のポート番号はそれぞれのホスト名の後にコロン「:」をつけて指定します。ポートが明示的に指定されなかった場合にはデフォルトで 80 が使われます。<br /> 前述の仮想ハブと同様に -I と -U というオプションがあり -I では sted.exe を Windows サービスとして登録し、-U を使うと、Windows サービスの登録を解除します。<br/><br/> <pre>Usage: sted.exe [ -i instance] [-h hub[:port]] [ -p proxy[:port]] [-d level] [-I|-U] -i instance : Instance number of the ste device -h hub[:port] : Virtual HUB and its port number -p proxy[:port] : Proxy server and its port number -d level : Debug level[0-3] -I : Install Service -U : Uninstall Service</pre> <pre>C:\winvpn> sted.exe -i 0 -h hub.example.com </pre> Windows サービスとして登録した場合には -i, -h, -p などのオプションはコントロールパネルの「サービス」にて「開始パラメータ」として指定します。<br /> &ref(http://www.whiteboard.ne.jp/~admin2/pict/service-sted-detail.png);<br /> サービスとして使用する場合ひとつのプロセスしか起動できない(私が知らないだけかとおもいますが)ので、ひとつの仮想 NIC インスタンスしか利用することができません。<br /> コマンドプロンプトから起動する場合には、複数のコマンドプロンプトを開いて、各コマンドプロンプト上で別々に sted.exe を起動すれば複数の仮想 NIC インスタンスを同時に利用することができます。((ただし、使われている仮想 NIC ドライバのインスタンスを知る方法がありません。0,1,2,3.. と増加していくので、それで推測していただくしかないです。要改善です。))<br/><br/> <h2 id="">設定例 [#s5855f76]</h2> <h3 id="">Host To Lan [#x879f799]</h3> ホストを遠隔地の内部ネットワークに参加させるための設定です。(たとえば、インターネット経由で自宅の LAN に参加する。)Windows のブリッジ接続機能を使って 遠隔地の Windows マシンにつながっているプライベートな内部ネットワークに仮想的に接続します。<br/><br/> &ref(http://www.whiteboard.ne.jp/~admin2/pict/net_config_sample.GIF);<br/><br/> <h4 id="">HostB(Windows7) の設定 [#dd7ec0c2]</h4> <ol class="list1 list-indent1"><li>ste 仮想 NIC ドライバーをインストール。(下図ではローカルエリア接続 2)<br /><br />&ref(http://www.whiteboard.ne.jp/~admin2/pict/network-connection-3.png);</li> <li>内部ネットワークの NIC(下図ではローカルエリア接続3)と Ste 仮想NIC(下図ではローカルエリア接続 2)とをブリッジ接続。<br />双方のアダプタのアイコンをコントロールキーを押しながら選択し、右クリックして「ブリッジ接続」を選ぶ<br /><br />&ref(http://www.whiteboard.ne.jp/~admin2/pict/network-connection-add-bridge.png);</li> <li>ネットワークブリッジに の内部ネットワークの IP アドレスを設定。<br /><br />&ref(http://www.whiteboard.ne.jp/~admin2/pict/ip-setting-bridge.png);</li> <li>仮想ハブデーモン stehub.exe を起動(例ではポート8888番を使用)<br /> <pre>C:> \Program Files\SteVPN\stehub -p 8888</pre></li> <li>仮想 NIC デーモンを起動。ローカルの仮想ハブに接続に行く。 <pre>C:\>\Program Files\SteVPN\sted.exe -h localhost:8888 debuglevel = 0 device path = \\.\STE0 Successfully opened STE device Successfully connected with HUB</pre></li></ol> <h4 id="">HostA(Windows XP) の設定 [#dd7ec0c2]</h4> <ol class="list1 list-indent1"><li>ste 仮想 NIC ドライバーをインストール。(下図ではローカルエリア接続 3)<br /><br />&ref(http://www.whiteboard.ne.jp/~admin2/pict/network-connection-xp.PNG);</li> <li>仮想NIC に遠隔地の内部ネットワークの IP アドレスを設定。<br />(もし遠隔地の内部ネットワークにDHCPサーバがあればそこから自動割り当てすることも可能)<br /><br />&ref(http://www.whiteboard.ne.jp/~admin2/pict/ip-setting-xp.PNG);</li> <li>仮想 NIC デーモンを起動。HostA の仮想ハブに接続に行く。 <pre>C:\>\Program Files\SteVPN\sted.exe -h HostA:8888 debuglevel = 0 device path = \\.\STE0 Successfully opened STE device Successfully connected with HUB</pre></li></ol> <h3 id="">Host to Host [#j6cf3be0]</h3> それぞれ別々の物理ネットワークに繋がった2つのホスト(Windows XP と Solaris)を、仮想ハブを通じで、同一ネットワークに繋がっているように見せるための設定です。以下の例では分かりやすくするために、仮想ハブと仮想 NIC デーモンが起動されているホストを別のホストにしていますが、仮想ハブは仮想 NIC デーモンが起動されているホスト上で動作させても問題ありません。また、Windows, Solaris どちらで仮想ハブを実行してもかまいません。<br/><br/> &ref(http://www.whiteboard.ne.jp/~admin2/pict/net_config_h2h.gif);<br/><br/> <ul class="list1 list-indent1"><li>ホストA ... 仮想ハブデーモンが動作するホスト。(Windows XP)</li> <li>ホストB ... 仮想 NIC ドライバがインストールされており、仮想 NIC デーモンが動作するホスト。(Windows XP)</li> <li>ホストC ... 仮想 NIC ドライバがインストールされており、仮想 NIC デーモンが動作するホスト。(Solaris 10)</li></ul> <h4 id="">ホストA(Windows XP)の設定 [#d2c4dd1c]</h4> <ol class="list1 list-indent1"><li>仮想ハブデーモン stehub.exe をコピーしたディレクトリに移動。(例では C:\winvpn に実行可能ファイルをコピーしてあると仮定) <pre>C:\> cd \winvpn C:\winvpn></pre></li> <li>仮想ハブデーモンを起動(TCP ポート 8888 で待機) <pre>C:\winvpn> stehub.exe -p 8888</pre></li></ol> <h4 id="">ホストB(Windows XP)の設定 [#t50fd35c]</h4> <ol class="list1 list-indent1"><li>仮想 NIC ドライバーをインストール。<br />&ref(http://www.whiteboard.ne.jp/~admin2/pict/windows_network.png);</li> <li>仮想 NIC の IP アドレスを設定。(上図では「ローカルエリア接続 2」)<br />&ref(http://www.whiteboard.ne.jp/~admin2/pict/windows_ip_setting.png);</li> <li>仮想ハブデーモン sted.exe をコピーしたディレクトリに移動。(例では C:\winvpn に実行可能ファイルをコピーしてあると仮定) <pre>C:\> cd \winvpn C:\winvpn></pre></li> <li>仮想 NIC デーモンを起動。仮想ハブに接続に行く。 <pre>C:\winvpn>sted.exe -h hostA:8888 debuglevel = 0 device path = \\.\STE0 Successfully opened STE device Successfully connected with HUB</pre></li></ol> <h4 id="">ホストC(Solaris 10)の設定 [#f6ef2c9f]</h4> <ol class="list1 list-indent1"><li>仮想 NIC ドライバーをインストール。 <pre>hostC # make install /usr/sbin/install -s -f /kernel/drv/sparcv9 -m 0755 -u root -g sys ste /usr/sbin/install -s -f /kernel/drv -m 0644 -u root -g sys ste.conf /usr/sbin/install -s -d /usr/local/bin /usr/sbin/install -s -f /usr/local/bin -m 0755 -u root sted /usr/sbin/install -s -f /usr/local/bin -m 0755 -u root stehub hostC #</pre></li> <li>仮想 NIC ste0 を設定 <pre>hostC # /usr/sbin/ifconfig ste0 plumb hostC # /usr/sbin/ifconfig ste0 192.168.0.2 up hostC # /usr/sbin/ifconfig ste0 ether 8:0:20:0:0:2 hostC # /usr/sbin/ifconfig -a lo0: flags=1000849 mtu 8232 index 1 inet 127.0.0.1 netmask ff000000 hme0: flags=1000843 mtu 1500 index 2 inet 172.29.80.33 netmask ffffff00 broadcast 172.29.80.255 ether 8:0:20:d3:da:8a ste0: flags=1001843 mtu 1500 index 3 inet 192.168.0.2 netmask ffffff00 broadcast 192.168.0.255 ether 8:0:20:0:0:2 hostC #</pre></li> <li>仮想 NIC デーモン sted を起動。仮想ハブに接続に行く。 <pre>hostC # /usr/local/bin/sted -h hostA:8888 Successfully connected with HUB Going to background mode hostC #</pre></li></ol> <h2 id="">解説 [#g9477d9f]</h2> <h3 id="">ste.sys: 仮想 NIC ドライバ [#za046673]</h3> カーネルモードで動作する仮想 NDIS ミニポートドライバです。上位プロトコルから渡された送信パケットをユーザモードプログラムである「仮想 NIC デーモン」に渡し、逆に「仮想 NIC デーモン」から渡されるデータをあたかも物理 NIC から受け取った受信パケットのように上位プロトコルに転送します。以下、ドライバの主な動作の流れをご説明します。<br/><br/> <h4 id="">ロード時: [#u0f34f7c]</h4> <ol class="list1 list-indent1"><li>NDIS ミニポートドライバのエントランスポイントである SteMiniportinitialize() が呼び出される。</li> <li>SteCreateAdapter() が呼ばれインスタンス毎の STE_ADAPTER 構造体が確保される。インスタンスは「インスタンス番号」で管理され SteAdapterHead という大域変数から参照されるアダプターインスタンスのリストに追加されていく。(Ste.sys ドライバがインストールされるたびにインスタンス番号は 0, 1, 2... と増えていく。)この中で送受信キューの確保、パケットプールの確保、各種初期化処理が行われる。</li> <li>SteRegisterDevice() が呼ばれ、この中でデバイスオブジェクトが作成され、「\DosDevice\STE<インスタンス番号>」という名前でこのデバイスオブジェクトへのシンボリックリンクが作成される。(ユーザモードの仮想 NIC デーモンとのデータの交換はこのデバイスを通じて IRP(I/O リクエストパケット)を使って行われる。)</li></ol> <h4 id="">パケット送信時: [#f390b43f]</h4> <ol class="list1 list-indent1"><li>NDIS ライブラリが仮想 NIC ドライバの SteMiniportSendPackets() 関数を呼び出し、送信すべきパケットが渡される。</li> <li>仮想 NIC ドライバは、自身の「送信キュー」にパケットをキューイング(StePutQueue())し、仮想 NIC デーモンが作成したイベントオブジェクトにイベントを通知(KeSetEvent())する。</li> <li>仮想 NIC デーモンは、イベントを通知されれると、ReadFile() を使ってドライバに対してデータの読み込み要求を行う。</li> <li>READ 要求の IRP がドライバに到着し、READ 要求の為のディスパッチルーチン(SteDispatchRead())が呼び出される。</li> <li>仮想 NIC ドライバンは「送信キュー」からパケットを取り出し(SteGetQueue())、パケットの中身のイーサネットフレームを IRP にセットし仮想 NIC デーモンに戻す(IoCompleteRequest())。</li></ol> <h4 id="">パケット受信時: [#g5d640b7]</h4> <ol class="list1 list-indent1"><li>仮想 NIC デーモンが WriteFile() を使ってドライバに対してデータの書き込み要求を行う。</li> <li>WRITE 要求の IRP がドライバに到着し、WRITE 要求の為のディスパッチルーチン(SteDispatchWrite())が呼び出される。</li> <li>仮想 NIC ドライバは初期化時に確保しておいた「パケットプール」から未使用のパケットを取り出し(SteAllocateRecvPacket())、仮想 NIC デーモンから渡された IRP に含まれているデータをパケットにコピーする(SteCopyPacketToIrp())。</li> <li>仮想 NIC ドライバは、データがコピーされたパケットを「受信キュー」にキューイング(StePutQueue())し、後で受信処理の関数(SteRecvTimerFunc())が呼ばれるようにタイマーをセット(NdisSetTimer())する。</li> <li>NdisSetTimer() により受信処理用の関数(SteRecvTimerFunc())が呼ばれ、仮想 NIC ドライバは「受信キュー」からパケットを取り出し(SteGetQueue())、上位プロトコルに対してパケットの到着を通知(NdisMIndicateReceivePacket())する。</li></ol> <h3 id="">sted.exe: 仮想 NIC デーモン(サービス) [#v3b02357]</h3> カーネルモードで動作する「仮想 NIC ドライバ」と「仮想ハブ」との間のデータの中継を行うユーザモードプログラムです。「仮想 NIC ドライバ」から受け取った Ethernet フレームは「仮想 NIC デーモン」によってカプセル化され、Socket を通じて「仮想ハブ」に転送されます。また、おなじく Socket を通じて「仮想ハブ」から受け取ったカプセル化された Ethernet フレームを開梱し、「仮想 NIC ドライバ」に渡す役割も持ちます。<br /> 仮想 NIC デーモンは起動すると 「\\.\STE<インスタンス番号>」 をオープンし、「仮想 NIC ドライバ」からのイベントを受信するためのイベントオブジェクトを作成(CreateEvent())します。その後、REGSVC という ste のオリジナルの IOCTL コマンドをドライバに発行(DeviceIoControl())して、作成したイベントオブジェクトのハンドルを「仮想 NIC ドライバ」に渡します。<br /> REGSVC IOCTL コマンドを受け取った「仮想 NIC ドライバ」は、仮想 NIC デーモンが渡してきたイベントオブジェクトのハンドルからイベントオブジェクトを得ます(ObReferenceObjectByHandle())。<br /> 仮想 NIC デーモンは ReadFile() を利用して、「仮想 NIC ドライバ」からデータ(中身は Ethernet フレーム)を受け取ります。受け取った Ethernet フレームは 4 バイトの倍数になるようにパディングされた後、stehead 構造体という簡単なヘッダーを付加され、socket(3SOCKET) を使って「仮想ハブ」に転送されます。<br/><br/> <pre>typedef struct stehead { int len; /* パディング後のデータサイズ */ int orglen; /* パディングする前のサイズ。 */ } stehead_t;</pre> 逆に、「仮想ハブ」からデータを受信した場合には上記の stehead 構造体内のデータサイズ情報を元に Ethernet フレームを再構築し、WriteFile() を使って、仮想 NIC ドライバに渡します。その後、仮想 NIC ドライバはあたかも実 NIC から Ethernet フレームを受け取ったように、それらを上位プロトコルに渡します。<br /> Solaris 版と違い、Windows 版ではバックグラウンドでの実行はできません。その代わり、-I というオプションを指定して起動すると、Windows サービスとして登録することができます。ただ、サービスとして動作する場合にはひとつの仮想 NIC のインスタンスに対してしか動作することができません。(複数の仮想 NIC インスタンスを同時に利用できないということです)これは、同一サービスのプロセスを複数起動させる方法がわからなかったためです。何か方法があると思うのですが・・。<br/><br/> <h3 id="">stehub.exe: 仮想 ハブ [#t80843af]</h3> 仮想ハブは、実際のハブのように、あるポート(仮想 NIC デーモンからの TCP 接続)からのパケットを他のポートへ転送する役割を持つます。<br /> コードは Solaris 版と共通で、Solaris 版と同様に TCP ポート 80 をリッスンしているサーバプログラムになります。。複数の仮想 NIC デーモンからの接続を管理し、また予想外の TCP 接続の切断を認識するために、各TCP 接続を conn_stat という構造体のリンクリストにて管理しています。<br/><br/> <pre>struct conn_stat { struct conn_stat *next; /* 次の conn_stat 構造体のポインタ */ int fd; /* FD */ struct in_addr addr; /* 接続してきている仮想 NIC デーモンのアドレス */ };</pre> <h2 id="">コンパイル [#z4bb914d]</h2> <h3 id="">コンパイル [#gd2fa0f2]</h3> コンパイルには Microsoft の WDK(Windows&#160; Driver&#160; Kit)を使用しています。<a href="" rel="nofollow">http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=11800</a>からダウンドードできます。<br/><br/> WDK をインストール後、「スタート」->「プログラム」->「Windows Driver Kits」->「WDK 7600.16385.1」->「Build Environments」->「Windows 7(もしくはXP)」 から 、「x86 Checked Build Environment」 か 「x86 Free Build Environment」を選びコマンドプロンプトを開きます。<br /> プロンプト上で、ソース を解凍したディレクトリに移動し、「build」コマンドを実行すると仮想 NIC ドライバである Ste.sys と、ユーザモードプログラムである仮想 NIC デーモン sted.exe、仮想ハブ stehub.exe が作成されます。<br/><br/> <pre>Y:\vpn-ste-win>build BUILD: Compile and Link for x86 BUILD: Loading c:\winddk\7600.16385.1\build.dat... BUILD: Computing Include file dependencies: BUILD: Start time: Tue Jan 03 01:08:41 2012 BUILD: Examining y:\vpn-ste-win directory tree for files to compile. y:\vpn-ste-win\exe\sted Invalidating OACR warning log for 'root:x86chk' BUILD: Saving c:\winddk\7600.16385.1\build.dat... 1>BUILD: Compiling and Linking y:\vpn-ste-win\exe\sted directory 2>BUILD: Compiling and Linking y:\vpn-ste-win\exe\stehub directory Configuring OACR for 'root:x86chk' - <OACR on> 1>Compiling - exe\sted\sted.c 2>Compiling - exe\stehub\stehub.c 2>Compiling - exe\stehub\getopt_win.c 1>Compiling - exe\sted\sted_socket.c 2>Compiling - exe\stehub\generating code... 2>Linking Executable - exe\stehub\i386\stehub.exe 1>Compiling - exe\sted\getopt_win.c 1>Compiling - exe\sted\generating code... 1>Linking Executable - exe\sted\i386\sted.exe 1>BUILD: Compiling and Linking y:\vpn-ste-win\sys directory 1>Compiling - sys\ste.c 1>Compiling - sys\ste_local.c 1>Compiling - sys\generating code... 1>Linking Executable - sys\i386\ste.sys BUILD: Finish time: Tue Jan 03 01:09:00 2012 BUILD: Done 13 files compiled - 5 Warnings - 2,544 LPS 3 executables built</pre> <h3 id="">コンパイル後のインストール [#k432e7fc]</h3> ste.sys 仮想 NIC ドライバのは Windows 7 の場合は前述の[[ドライバのインストール>#qbfe1556]]に従ってインストールします。<br /> Windows XPの場合は「コントロールパネル」->「ハードウェアの追加と削除」から「ハードウェアのウィザード」を起動して以下の要領でインストール行します。<br/><br/> <ol class="list1 list-indent1"><li>「ハードウェア追加ウィザードの開始」で「次へ(N)」をクリック</li> <li>「はい、ハードウェアを接続しています(Y)」を選択し、「次へ(N)」をクリック</li> <li>「新しいハードウェアデバイスの追加」を選択し、「次へ(N)」をクリック</li> <li>「一覧から選択したハードウェアをインストールする(詳細)(M)」を選択し、「次へ(N)」をクリック</li> <li>「ネットワークアダプタ」を選択し、「次へ(N)」をクリック</li> <li>「ディスク使用」をクリックし、「参照」から先ほど build をしたディレクトリ以下の \winvpn\sys\i386\netste.inf を選択し「OK」をクリック</li> <li>「Ste Virtual NIC」を選択し、「次へ(N)」をクリック</li> <li>「ハードウェアをインストールする準備ができました」から「次へ(N)」をクリック</li> <li>「ハード追加ウィザードの完了」がでたら「完了」をクリック。</li></ol> sted.exe 、stehub.exe デーモンは以下のディレクトリに作成されます。適当なところにコピーしてお使いください。<br/><br/> <pre>sted.exe <zip ファイルを解凍したディレクトリ>\exe\sted\i386\sted.exe stehub.exe <zip ファイルを解凍したディレクトリ>\exe\sthub\i386\sthub.exe</pre> <h3 id="">手動アンインストール [#k081b7f7]</h3> ドライバのアンインストールはデバイスマネージャから行います。<br/><br/> <ol class="list1 list-indent1"><li>「コントロールパネル」-> 「システム」から、「ハードウェア」タブをクリック。</li> <li>「デバイスマネージャ」をクリック。</li> <li>デバイスのツリーから、「ネットワークアダプタ」->「Ste Virtual NIC」を選び、右クリックのプルダウンメニューから「削除(U)」を選択</li> <li>「デバイス削除の確認」にて「次へ(N)」をクリック</li></ol> sted.exe、stehub.exe については適宜ファイルを削除してください。<br/><br/> <h2 id="">今後の課題 [#bd144f8b]</h2> <ol class="list1 list-indent1"><li>パフォーマンスの向上!!</li> <li>Windows サービスとして登録した場合にも複数の仮想 NIC を扱えるようにする</li> <li>仮想 NIC のインスタンス番号がわかるようにする。</li></ol>
: