Microsoft ネットワークを解剖する

第1回「NetBIOSでの通信と名前解決の仕組み」 -- Microsoftネットワークの混迷 --

現在のMicrosoftネットワークは、度重なる仕様拡張の結果非常に複雑かつ難解なものとなっている。 そこで今回は第一回目として、なぜ現在のような複雑な仕様になっているかを理解する意味でも、 Microsoftネットワーク仕様の拡張の歴史を追いながら、NetBIOS名での通信と名前解決の仕組みを解説していく。


図1のようにLMHOSTS や WINS で通信したいマシンの IP アドレスを正しく設定し、 ping レベルでは応答があるのに \\<サーバ名>\<共有名>でファイル共有ができないという事象がある。 原因としては LMHOSTS ファイルで指定したサーバ名と, サーバのコンピュータ名とが異なっていることが原因の場合が多いのだが, UNIX などで利用する /etc/hosts ファイルや DNS の設定では,サーバのホスト名と異なる呼び方(www や ftp など) を行っても問題なく通信できるのに, なぜ Microsoft ネットワークではだめなのか? 疑問に思っている方も多いであろう。

図1: 相手のコンピュータ名を正しく指定しないと通信できない
フレーム21のように、LMHOSTS に設定した本来のコンピュータ名(MISAKO)と異 なる名前(MISAKO2)で宛先を指定して通信を開始しようとしても、フレーム22 のように Called Name Not Present というエラーで通信できない
図1: 相手のコンピュータ名を正しく指定しないと通信できない

図1: 相手のコンピュー
		タ名を正しく指定しないと通信できない
フレーム21のように、LMHOSTS に設定した本来のコンピュータ名(MISAKO)と異 なる名前(MISAKO2)で宛先を指定して通信を開始しようとしても、フレーム22 のように Called Name Not Present というエラーで通信できない
図1: 相手のコンピュータ名を正しく指定しないと通信できない

従来マイクロソフトは、過去との互換性を保ちながら元々は小規模 LAN 用であった Microsoftネットワークのアーキテクチャを半ば強引に拡張していくことで、拡大するネットワークに対応してきたが、 上記の例をはじめ, ブラウジング機能等の各所に歪みが発生している。 また、華々しく宣伝されるアプリケーション開発関連の新機能に比べ、それらを影で支えるネットワークの技術は、 脇役にみられがちであり、細かい点での仕様変更なども詳細に解説されることもないままに提供され続けて来た。 このため、今に至るまで、Microsoftネットワークの仕様は曖昧もことしており、幾多の俗説が流布しているという状態である。 また Windows NT Server や SMS に付属の「ネットワークモニタ」というパケットキャプチャツールは、少なくとも Microsoft ネットワークのパケットの解析に付いてはそれなりに優秀なツールである(注1)にも関わらず、 仕様が不明のため、トラブルシューティングを行なおうにももままならないという状態であると感じている。

注1: Microsoft ネットワーク関連のパケットの解析に関しては他社製品に引けを取らないと感じているが、 半面Windows NT 付属のものは、自ホスト宛のフレームしかキャプチャできないという仕様の制限に加え、 フレームを取りこぼすなどの問題点もある。可能であれば SMS を購入して付属のネットワークモニタを利用してほしい。 SMS 本体をインストールせずにネットワークモニタだけをインストールするには, CD-ROM の直下の NMEXT\DISK1 というフォルダにある setup.exe を実行してほしい。なお, ネットワークモニタを利用するだけであれば、SMS の CAL は不要である。

インターネット時代を迎え、Windows 2000 では、ネットワーク環境としてTCP/IP, DNS, LDAP 等の標準技術を全面的に採用し、 遂にNetBIOSインタフェースなどの従来のアーキテクチャから全面的に脱却する道を選ぶに至った。過去との互換性は犠牲になるが、 場当たり的な機能拡張には限界があり、やむを得ない当然の成り行きと言えよう。 今後数年を費やして徐々にWindows 2000 やその後継OSへの移行が進んでいくことになろうが、 当面従来のアーキテクチャも無視することはできないのもまた事実である。 そこで本連載では、これまでの集大成として、Microsoft ネットワークのアーキテクチャの全貌について詳細に見ていくとともに、 「ネットワークモニタ」の出力を解説することで自力でキャプチャしたパケットの解析が行なえるだけの知識を身に付けることを目標としたい。

NetBEUIの紹介

現在のMicrosoftネットワークの基本となるアーキテクチャが作成されたのは、当時はNOS(注2)としては Novell Netwareが主流でありクライアントOSはMS-DOS全盛の頃の時代である。 ネットワークは部門に閉じたファイル/プリンタ共有のためのネットワークであり、物理的にも1つの物理セグメントに閉じていて、 クライアント台数も限られていた。

注2: NOS とは Network OSのこと。当時はネットワークに対応したOSを特別にこのように呼ぶことがあった。 当時の Microsoft もLAN Manager ServerというNOSを出荷していた。

当時のMicrosoftネットワークで利用されていたのが現在NetBEUI(注3) と呼ばれているトランスポート層からデータリンク層(注4)にかけてのプロトコルである。

注3: この名称で呼ばれるようになったのは、もっと後のことである。 当時は単なるベンダ独自プロトコルの一つであり、インタフェースの名称でもあるNetBIOSと呼ばれていた。 なお、NetBIOSは、元々1984年頃にIBMが定めたベンダ規格で、 最初はIBM製LANカードのROMに書き込まれていたネットワーク用の低レベルなAPIのことであった。

注4: ネットワーク層/データリンク層などはOSI階層モデルの用語である。 詳細については関連書籍などを参照してほしい。

MS-DOSという限られた資源しか利用できないOS上でネットワーク機能を利用するため、 極力アーキテクチャを簡単にすることが求められた中で設計されたこのプロトコルは、ルーティング機能を持たず、 ブロードキャストベースで名前解決を行なって通信するというものであった。 従ってOSI参照モデルに無理やり当てはめればデータリンク層からトランスポート層までのプロトコルとなるが、 実際はこれらの層の区別がされている訳ではない。 現在は、NetBEUIをメインで利用している部署は殆んどないであろうが、 Microsoftネットワークがなぜ現在のように複雑な構成になっているかを理解する上では、 Microsoftネットワークが最初に採用したプロトコルであるNetBEUIについての理解が欠かせない。 そこで多少回り道になるが、NetBEUI での通信方式について説明しよう。

NetBEUIの通信方式と名前解決

NetBEUIはどのようにして通信を行っていたかについて、図2のネットワークキャプチャを参照しながら解説しよう。 このネットワークキャプチャは、LAN Manager 2.1c の MINI というマシンを起動し、 LMONYO というアカウント名でログオンしてから、Windows NT Server 4.0 Service Pack 6 の MISAKO というコンピュータ名のマシンの TEMP という名称の共有にアクセスしたところである。

名前解決の仕組み

図2: NetBEUI での通信
図2: NetBEUIでの通信

34 番目フレームである のName Query(0x0A)MINI <00>() -> MISAKO という NetBIOS のブロードキャストに着目すると、送信元が MINI<00> 受信先が MISAKO<20> であることが分かる。 それに対して次フレームでは MISAKO<20> より MINI<00> に Name Recognize(0x0E) という応答が返却され、以後は互いの MAC アドレスを指定しての通信が続いている。 この時フレームを受信したマシン(MISAKO)は、宛先の「NetBIOS名」の確認という動作を行なっている。それが自分が「登録」という処理を行ったNetBIOS名の一つと一致していれば、そのパケットは自分宛だと判断して、34 番目のようなフレームを返信する訳である。 なお MINI<00> という記述は、MINI の後にスペースが 15バイト目まで続き、16 バイト目が 16 進法で 00 である 16 バイトの文字列を意味する。詳細は後述する NetBIOS 名の説明を参照して欲しい。なお、16 進法で 20 は空白文字のため、図2 では MISAKO<20> が単に MISAKO と書かれているように見える。

名前の「登録」の仕組み

この方式では、物理セグメント中に同じNetBIOS名のマシンが複数台いると、一対一の通信が正常に行えない(注5)。 このため、NetBEUIを理解する各マシンは起動時(正しくはプロトコルの有効化時)に「名前の登録」という動作を行い、 自分が受信したいNetBIOS名で受信してよいかどうかを問い合わせる。 図3 を見て欲しい。 5〜7のフレームでは Add Name Query (0x01) Name = MINI<03> という通信で、MINI<03> という名前をブロードキャストで追加(登録)して良いか問い合わせているのが分かる。 ここで既に同じ名前を登録しているマシンがあった場合は、その旨を応答しなければならない。 3回繰り返しても応答がなければ、問い合わせを行なったマシンが名前を「登録」する。

注5: 後述する「グループ名」のように、重複した登録を許す名前も存在する

図3: NetBEUIの登録処理
図3: NetBEUIの登録処理

このように、NetBEUI ではブロードキャストベースで名前を解決する。 また名前の重複を検知する手段としては名前の登録という処理を行っている。

NetBIOS名の一意性

ここで重要なことを一つ指摘しておこう。NetBIOSインタフェースを用いるNetBEUI プロトコルでは、 冒頭の図1で説明したようにネットワーク層でも「NetBIOS名」で通信相手を識別しているという事である。 TCP/IP の場合、通信相手を名前(ホスト名)で指定しても、それは hosts ファイルやDNS 等によって「解決」され実際にネットワークにパケットを送出する時点ではIP アドレスに変換されている。 しかし NetBEUI の場合、ネットワーク上を名前の情報がそのまま流れ、通信相手を識別するために用いられているのだ。 つまりTCP/IPに例えると、NetBEUIの世界ではNetBIOS名こそが通信相手を一意に識別するIPアドレスと同等の概念であると言える。 NetBEUI の世界だけで考えると、それなりに合理的な仕様であるが、これからおいおい解説していくように、 この仕様が混乱を招く要因の一つになっている。

NetBIOS 名

話が前後するが、NetBIOS名について整理しておく。 当初IBMが規格を定めた時点では16バイト以内という規定のみであった。 しかしMicrosoftは、16バイト目を機能を表す識別子として位置づけ、いわゆる「名前」は15バイト以内という形でNetBIOS名を再定義したのだ。 図5 のように、名前が15 バイトに満たない場合、15 バイト目まではスペース文字(0x20)で埋められる。 なお通常はMISAKO<00>のようにして名前と識別子を表記することが多いので、この連載でもそのように表記する。

図5: NetBIOS名
MISAKO<00> のバイト表記
,M,I,S,A,K,O, , , , , , , , , ,0x00, <-- 16バイト目が 0x00

本連載はMicrosoftネットワークを対象としているため、以後NetBIOS名といった場合は、Microsoftが再定義したNetBIOS名を指すものとする。 16バイト名の識別子の主なものを表1に示した。 もちろんこれ以外にもアプリケーションが独自の識別子を登録している場合もある。 Microsoftが登録しているものについては、「J042523 NetBIOS名の16文字目の文字(注5.5)」 や、 Windows NT Server 4.0 リソースキット中のネットワーキングガイド P.732を参照するとよいであろう。 各機能が利用しているNetBIOS名については、連載中で随時説明していく。

表xx1: NetBIOS名16番目の識別子
種別内容
00ユニークワークステーションサービス名
1Bユニークドメインマスタブラウザ名
1Dユニークマスタブラウザ名
20ユニークサーバサービス名
00グループドメイン/ワークグループ名
1Cグループドメインコントローラ
1Eグループセグメント内のポテンシャルブラウザ

注5.5: 以後の連載中でも Qxxxxxx や Jxxxxxx というマイクロソフトの技術情報の表記は頻出する。 これらの情報は Web 上にあるので, 以下のようにして参照して頂きたい。
Q123456 の場合
http://support.microsoft.com/support/kb/articles/Q123/4/56.asp
J123456 の場合
http://www.microsoft.com/japan/support/kb/articles/J123/4/56.htm

この識別子は、TCP/IPに例えるとポート番号のようなものだと考えると分かりやすいだろう。

ユニーク名とグループ名

ここまで一つのNetBIOS名を一台しか登録できない場合の動作について説明したが、名前にはグループ名とユニーク名という区別がある。 ユニーク名は一台のマシンしか登録できない名前だが、グループ名は複数のマシンが登録することができる。 再度図2を見て欲しい、下のペインに Netbios Name Type = Unique Name という行があり、 この通信はユニーク名に対する通信であることが分かる。 グループ名を宛先に指定されたフレームは、そのグループ名を登録した全てのマシンが受信することができる。 一種のマルチキャストのようなものだと考えるとわかりやすいであろう。

NetBIOS over TCP/IP の動作原理

ここまで、NetBEUI の動作原理について説明したが、これを踏まえて現在の主流である NBT(NetBIOS over TCP/IP)について説明する。 NetBIOS インタフェースは、元々下位プロトコルとして NetBEUI のみをサポートしていたが、これを TCP/IP(注6) プロトコル上に移植したものが NBT になる。

注6: TCP/IPの実装についての詳細は本論とは外れるので割愛する。関連する書籍などを読んでほしい。

NBT での名前の登録と通信

NBT で名前を登録してから通信を行なうまでの一連の流れを WINS クライアントでない環境について解説する。 後述するように WINS クライアントとなっている場合は動作が大きく異なる。 NBT が有効になっているクライアントは、NetBIOS名の登録や解放といった 動作をUDP/137 を用いたローカルサブネットへのブロードキャストで行う。 このパケットをキャプチャした様子を図6に示す。なおOSは Windows NT Server 4.0 Service Pack 3 である。 フレーム46から49まで, 約 0.7 秒間隔で合計4回(注7)にわたり, NS:Registration req. for HOME<1E> という形で HOME<1E> の登録が行われている。 マシンがマルチホームでない限り(注7.5), これらの動作については基本的にNetBEUIの場合と同様であり理解しやすい。

注7: 仕様的には3 回の筈だが、実験した限り 4 回行なわれていた。

注7.5: マルチホームとは, 複数のLANカードを持っているマシンのことである。 Microsoft ネットワークの仕様はそもそもマルチホームマシンの存在を考慮していないため, マルチホームのマシンは様々な点で仕様上の不具合や問題点が存在する。 本来はマルチホームマシンの特性についても解説すべきではあるが, 今回は紙面の関係上, 残念ながら割愛した。

図6: NBTの名前登録
HOME<1E> というグループ名を登録するところ
図6: NBTの名前登録

NBT での名前解決

同様に同一物理ネットワーク内に通信相手がいる場合の名前解決の動作を図7 でみてみよう。 これは MAYUMI という Windows 98 SP1 のマシンが MISAKO という Windows NT Server 4.0 SP6a のマシンの名前を問い合わせたところである。 NetBEUI の場合とほぼ同様に、フレーム4ではローカルサブネットへのIP ブロードキャストパケットで MISAKO<20> という名前の問い合わせが行われ、それに対してフレーム5で名前を登録しているMISAKOがユニキャスト(注9)で MAYUMI に対して Success というステータスで応答している。 なお、あるマシンがNBTレベルで登録した名前は図8 のように nbtstat -a コンピュータ名(注8)等で確認できる。

注8: nbtstat -A <IP アドレス> や nbtstat -n 等の関連オプションもある。

また、マシン停止時には図7.5 のフレーム10から12のように、名前を解放するためのパケットが送出される。 これにより、後述するNetBIOS名キャッシュにエントリをキャッシュしているマシンに対して、エントリが無効になったことを通知する。 この動きについてはNBTの説明中で詳しく解説する。

注9: ユニキャスト ブロードキャストに対し、特定の相手を指定して送信されるパケットをユニキャストという。

図7: NBT での名前解決
図7: NBT での名前解決

図7.5: NBT での名前解放
図7.5: NBT での名前解放

図8: nbtstat での登録した名前の一覧
各マシンが登録を試行したNetBIOS名とその結果が一覧できる Status が Conflict になっていたら, 名前の登録を試行して失敗したことがわかる
図8: nbtstat での登録した名前の一覧

論理ネットワークを越えた通信

ここまでは同一物理セグメント内に対して NBT で通信を行なう際の動作をみてきた。同一セグメントの場合は NBT でも NetBEUI と基本的には同様の方式で通信を行なうが、NBT では下位層が TCP/IP のため、論理ネットワークを越えた通信が可能である。 しかし、別ネットワークに存在マシンに対しては、ブロードキャストで通信を行うことができないため何らかの方法で相手の名前解決する必要がある。この解決策として考え出されたのが LMHOSTS ファイルである。 元来 LMHOSTS は hosts ファイルとほぼ同様に、コンピュータ名とIPアドレスを対応づけるだけの役割しかなかったが、Windows NT 3.1 でいわゆるNTドメインが実装されたことに伴い、Windows NT 3.1/Windows 95 以降ではLMHOSTSも明示的にNetBIOS名を扱えるように拡張された。具体的には表xx1.5を参照のこと。なおもともと行の # 以降はコメントと見なすのが LMHOSTS の仕様のため、拡張された記述を用いた LMHOSTS ファイルを従来の LAN Manager クライアントで用いても、# を用いて表現された特性が無視されるだけでエラーにはならないように考慮されている。

表1.5: LMHOSTS の主な機能拡張点
文法意味
x.x.x.x コンピュータ名 #PRE後述するNetBIOSキャッシュに強制的に登録する
x.x.x.x コンピュータ名 #DOM:ドメイン名x.x.x.x のIPアドレスを ドメイン名<1C>のインターネットグループに登録する。詳細は今後の連載で説明する
x.x.x.x コンピュータ名 #MH登録されたコンピュータ名のマシンは、マルチホームであると見なす。マルチホームについては注7.5を参照のこと
これ以外にも別マシンのLMHOSTSをインクルードするなどの機能が拡張されているが名前解決に直接関係がないので説明は省略する。

注9.5: LMHOSTS ファイルの詳細な文法に付いては Windows NT Server 4.0 リソースキット中のネットワーキングガイド第10章(P.491) LMHOSTS ファイルの使用方法や、Q102725: LMHOSTS File Information and Predefined Keywords 等を参照して頂きたい。

なお図9 のように、LMHOSTS に記述した情報は、ローカルサブネットにブロードキャストを行った後で参照される。当時はサブネット越えの通信を行うのは稀であったと考えられるので、妥当な仕様であったと考えられる。

図9: LMHOSTS ファイルのある環境でのパケットキャプチャ
192.168.2.3 のマシン(D-ANGEL)上で net use \\1st-servant\ipc$ を行なったときの結果 フレーム1から3でローカルサブネットに対してブロードキャストを行ない、失敗してから LMHOSTS を参照して、フレーム 7で直接別サブネットのマシンに接続に行っている。なおOSは、両方とも Windows NT Server 4.0 Service Pack 5 、 192.168.2.3 のマシンには、図9.1 のような LMHOSTS が設定されている。
図9: LMHOSTS ファイルのある環境でのパケットキャプチャ

図9.1: 192.168.2.3 のマシン上の LMHOSTS
192.168.1.2 1st-servant

NetBIOS名とIPアドレス

ここで注意したい点がある。LMHOSTS では、相手の名前(NetBIOS名)を正しく指定しておかないとIPレベルでは対象のマシンにパケットが届くにも関わらず、NetBIOSレベルでは通信を行うことができない。 NBTだけで考えれば、この仕様は非常に不可思議であるが、先ほど説明したNetBEUI の通信方式と併せて考えれば、なぜこのような仕様になっているかが理解できよう。 図10のように、NBTとは、NetBIOSインタフェースを実装するためにデータリンク層以下のNetBEUIの部分を無理やりTCP/IP上にカプセル化して実装したものだ。そのため、せっかくTCPの機能を使ってユニキャストで送付したパケットについても、宛先のホストは自分の登録したNetBIOS 名と一致するかどうかを確認す 二度手間の動作を行ってしまう。このような仕様の問題はこの後も幾つか解説するが、その殆んどは、元来単一物理セグメント内にブロードキャストを行うことでネットワーク層レベルの通信をするNetBEUIを用いてきたNetBIOSを、無理やりにTCP/IP上に実装したことに派生する問題であるといってよい。

図10: NBT の「カプセル化」
本来2,3層付近の機能を含むNetBEUIを無理やり4層のTCP上に実装したものだと考えると分かりやすい
図10: NBT の「カプセル化」

コンピュータ名とホスト名

ここで、TCP/IPでいうホスト名(注10)とコンピュータ名はどう違うかというテーマについても整理しておきたい。

注10: ホスト名 ホスト名の定義に付いては曖昧な点もあるが、ここではUNIX等で通信相手を指定する際に用いられる名前のこととして定義する。

ホスト名はIPアドレスにつけられたエイリアス名であり、TCP/IPレベルで実際の通信を行う際には全てIPアドレスに変換される。 UNIX のソケットAPI を直接用いるプログラミングを行ったことがあると良くわかると思うが、通信相手を識別する sockaddr 構造体に格納されるのはあくまでIPアドレスである。 ホスト名はユーザ側で事前にgethostbyname() 関数などを用いてIPアドレスに変換して構造体に格納する必要がある。 従って図11のように、機能上は最終的に正しいIPアドレスに変換されさえすれば、どのようなホスト名を用いて相手を識別しても構わない (注11)。

注11: HTTP/1.1 のように、通信相手を識別する名前によって動作を変更するプロトコルもあるが、 これはアプリケーション層が行っている実装であり、名前の情報もアプリケーション層で持っている。 ネットワーク層では、あくまでIPアドレスで通信を行っている。

図11: コンピュータ名とホスト名
図11: コンピュータ名とホスト名

アプリケーションが指定されたホスト名は IP アドレスに変換されてネットワーク上を流れるため, 最終的にIP アドレスさえ一致していれば違うホスト名(Host100)として自分を認識しているマシンも受け取ることができる。 一方NetBIOS の場合は, 最終的に送信先が自分のコンピュータ名と同じかどうかで自分宛の通信かどうかを確認するため, 送信元(Comp1)が送信先として指定したコンピュータ名が送信先の実際のコンピュータ名と一致しないと通信できない。

一方コンピュータ名はNetBIOSインタフェースで通信相手を識別するのに用いられる「アドレス」である NetBIOS名にそのまま用いられるものであり、結果としてネットワーク上での一意性が保証される必要がある一種のアドレスである。 両者とも「名前」という言葉がついているので、混同されることが多いが、その意味するところは全く異なっている。 これを理解することが、Microsoft ネットワークを理解する第一歩になろう。

CIFS

ところで、Windows NT 4.0 以上や、Windows 98 以上のOSにおいては、ファイル共有などを行う際に \\x.x.x.x\share_name のように、通信先のコンピュータ名を指定する代わりに通信先のIPアドレスを直接指定することも可能になっている。 これは、CIFS (Common Internet File System)(注12)という NetBIOS をマイクロソフト流にインターネット対応させた規格に従った通信が可能になっているためである。 図12 は共に Windows NT Server 4.0 Service Pack 5 のマシン同士でのIPアドレスを指定しての通信をキャプチャしたものである。 フレーム2で *<00> という名前解決要求を 192.168.1.2 宛に行っていることに注目してほしい。この *<00> というアドレスは特殊なアドレスであり, CIFS で通信を行うことを示すものである。パケットを受け取ったマシンが CIFS に対応している場合, フレーム5のように, 自分が登録しているNetBIOS名の一覧(nbtstat -A で取得できるのと同等の情報)を含む応答を返送するので, 通信元のマシンは, そのパケットをみて, 最終的にはフレーム9のように, 相手のコンピュータ名(上記の例では 1st-servant)を指定して通信を開始するという仕様になっている。 ただし、この方法では通信したいNetBIOS名の識別子の情報を与えることができないため、通信先は識別子 0x20 のファイル、プリンタ共有サービスのみとなっている。

図12: \\192.168.1.2\ipc$ 宛の通信
フレーム5 の応答の内容から, 192.168.1.2 は WATER というドメインに所属し、 1ST-SERVANT というコンピュータ名のマシンであることがわかる 図12: \\192.168.1.2\ipc$ 宛の通信

注12: CIFS についての詳細な情報はMSDNや http://www.cifs.com/ からたどれる各種リンクから入手できる。RFCのドラフトとしてブラウジングを始め、 幾つかの仕様が提示されたが、結局正式なRFCになることはなかった。

WINS 環境

ここまでNBTについて説明を行ってきた。しかし、基本的にここまでの話は CIFS を除き Windows NT 3.1 当時のアーキテクチャである。 LMHOSTS を用いた名前解決により、何とかサブネットを越えるNetBIOSインタフェースの通信が可能になったが、 管理が煩雑なことに加え、名前の登録などの機能をブロードキャストに頼っているために、一部の機能を利用することができなかった。 これに対する解として Windows NT 3.5 でマイクロソフトが実装したのがWINSである。WINS の仕様の一部は NBNS(NetBIOS Name Service)として、RFC1001, RFC1002 で規定されている NBT の仕様に含まれており、 筆者も関わっているオープンソースソフトウェアの Samba では、この規定を元に UNIX 上で動作する WINS サーバを実装することが可能になっている(注13)。 なお, WINS サーバ自身の実装に関する記述は, ネットワークパケットレベルでの名前解決に直接関連する事項ではないため, 紙面の関係もあって今回は割愛した。

注13: Samba の WINS は複製が行えないが、これはRFCで規定されておらず、 Microsoft の WINS サーバは独自の方式で複製を行っているためである。この他ブラウジング関連や DNS との連携などで、 Microsoft の WINS は独自の拡張を行っている。

WINS の登場により、やっとのことで複数ネットワークにまたがった環境において、 Microsoftネットワークの機能を充分に利用することが可能になったといえる。 しかし、WINSの導入により、Microsoftネットワークの仕様は更に複雑になった。 以下WINSを導入したWINS環境について説明していく。

名前の登録

WINS クライアントになっているマシンの起動時の名前登録のパケットをキャプチャしたものが図13である。 フレーム31から33をみると一目で分かるとおりブロードキャストではなく、プライマリWINS サーバ(WINSSRV) に対して名前の登録を行なっているのが分かる(注14)。 また、ブロードキャストの場合と異なり、フレーム34から36で登録に成功したという応答が戻るところも異なる点である。

注14: ブラウジング関連など、一部のブロードキャストベースである必要があるエントリ (ワークグループ名<1d>など)は, 登録自体は成功するが名前解決時にそのエントリは常に無視されるなどの特殊な処理が行われる。 詳細は、次回以降で連載予定のブラウジングの説明のところで解説する。

図x13: WINS 環境における名前の登録
図x13: WINS 環境における名前の登録

また, WINS サーバが指定されているにも関わらず, WINS サーバに接続できない場合は, レジストリ(注15)で設定された時間の1/8の時間毎にWINSサーバへの接続を試み, 4回試みても接続できない場合(つまり設定された時間の半分を過ぎても接続できない場合)は通信先のWINSサーバを切り替えて, 4回同様の登録の試みを行うという動作を繰り返す。 このレジストリのデフォルトの値は16分のため, 以下のような動作を行う

  1. (1)クライアントがWINSサーバに接続
  2. (2)プライマリWINSサーバに接続するが動いていないので接続できない。
  3. (3)セカンダリWINSサーバに接続するが動いていないので接続できない。
  4. (4)セカンダリWINSサーバに2分毎に8分間接続を試みるが失敗。
  5. (5)プライマリWINSサーバに2分後とに8分間接続を試みるが失敗。
  6. (6) (4)(5)を続ける

注15: Q154409: Setting WINS Clients Refresh Intervals to Occur Infrequently を参照のこと。ただし, 当方で検証した限り Windows NT での該当するレジストリの名前は InitialRefreshTimeout ではなく InitialRefreshT.O. であった。

登録に成功した場合は, WINS サーバ側から登録成功のパケットが返却されるが, そこには登録した情報の TTL (有効期限) が記述されている。クライアントは TTL の半分を過ぎると名前登録の更新要求を行う。 登録には成功したが, 更新の時点で WINS サーバとの通信ができなくなった場合は, 5分毎に自分が登録した WINS サーバへの問い合わせを繰り返す。 当方が確認した限り, この動作はWINSサーバへの通信が回復するか, 何らかの名前解決要求が別の WINS サーバで解決されるまで行われる(注16)。 これもパケットキャプチャで確認を行ったが, 紙面の関係もあるため, 省略する。

注16: 切り替わる気配がなかったため, 一昼夜そのままにしておいても5分毎の登録行為を継続していた。 その後新たな名前解決を行ったところ, 最終的に通信可能なWINSサーバに問い合わせて名前解決が行われたが, そのタイミングで名前解決を行ったWINSサーバに対して登録の通信も行われるようになった。

名前の解放

マシン停止時(サービス停止時)には名前解放のパケットが送信され、WINS データベース中のエントリを解放する。 この様子をキャプチャしたのが図14である。ブロードキャストの場合と異なり、解放要求は WINS サーバに送付され、 また応答が WINS サーバから返却される。例えば、フレーム1253 の NS:Release req. for MAYUMI<00> に対して、フレーム1256で Success という結果が応答されている。

図14: WINS 環境における名前解放
図14: WINS 環境における名前解放

WINS クライアントと非WINSクライアントの間の不整合

このようにWINSを利用することで, 名前登録のブロードキャストトラヒックは確かに減少するが、 WINSサーバと通信できる場合, 該当のWINS サーバ上で重複していない名前はとりあえず登録されるので、 後でローカルサブネットや同じWINSサーバを指定していないクライアント中にたまたま同じコンピュータ名のマシンがあると、 マシン起動後暫くして、登録した名前が重複し、名前の登録が重複するという事象が発生してしまう。 Microsoft ネットワークの仕様として登録が重複(conflict)した名前は無効になってしまうため, 突如通信できなくなるといった事象が発生する。 従って, WINS を利用する場合はすべてのクライアントをWINSクライアントとして構成するか, 後述するWINSプロキシを利用することが強く推奨される。

WINS プロキシ

Windows NT 3.5 以降には, 非WINSクライアントが間接的に WINS サーバを利用できるように, WINS プロキシという機能が実装された。なお Windows NT4.0 以降では需要が減少したと判断されたためか, レジストリ(注14.5)を直接編集しないとこの機能は有効にならない。

注14.5: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netbt\Parameters に EnableProxy: REG_DWORD というエントリを追加して値を 1 にする。

WINS プロキシのマシンは, 図14.5 のように bノードによる名前解決パケットを受信して, それをあらかじめ設定した WINS サーバに送信することができる。 非WINS クライアントが多かった昔は有用な機能であるが, Windows 95 以降のOSは WINS クライアントになれるので, 現状この設定を行うメリットはないであろう。

図14.5: WINS/プロキシの動作概念図

WINS サーバが同時に WINS プロキシになることはできない。 またWINS プロキシはブロードキャストベースのクライアントに対するサービスであるため, 各サブネット毎に必要である。
図14.5: WINS/プロキシの動作概念図

名前解決

WINS の実装と共に名前解決機能も拡張された。各所に同様の図があるが、一応 図15 に現在筆者が理解している名前解決の順序を記載しておく。以下注意すべき点を記述する。 なお、以下のように名前解決の機構は不可解とは言わないまでも各種の設定が影響し、非常に繁雑である。 名前解決のトラブルシューティングを行なうときにはこれらの仕様を把握した上で、問題のマシンの設定もしっかり把握する必要がある。 以下, 個々の名前解決の方式について解説する。

図15: NetBIOS名の名前解決の順序
図15: NetBIOS名の名前解決の順序

NetBIOS ネームキャッシュ

名前解決を行なった NetBIOS 名は、デフォルトで 600秒の間(注17)キャッシュされるが、 これを NetBIOS ネームキャッシュという()。 現在どのようなデータがキャッシュされているかは 図16 のようにnbtstat -c で確認できる。 また LMHOSTS 内で #PRE を付けたエントリは LMHOSTS ファイル読み込み時に自動的にキャッシュに格納され、 以後永続的にキャッシュされる。この為、WINS 環境においても、NetBIOS 名のエントリを #PRE 付きで LMHOSTS ファイルに記述しておくことで、その名前の名前解決を高速に行なうことが可能である。 ただしデフォルトで(注17.3)キャッシュされるのは100エントリまでである。

注17: NetBIOS ネームキャッシュ自体は WINS の使用とは無関係に存在する

注17.3: Q102725 にNetBIOSネームキャッシュの最大エントリ数を変更する方法が記述されている。 上記ドキュメント中の MaxPreload を参照して欲しい。

図16: nbtstat -c の結果
図16: nbtstat -c の結果

現在キャッシュされているエントリとキャッシュされる残り時間が表示されている。 キャッシュ時間が-1 となっているのは LMHOSTS で静的に登録されたエントリで有効期限切れにならない。 なお、残り時間は 10 秒単位でしか更新されない。

ノードタイプ

ノードタイプとは、WINS と ブロードキャストの名前解決順を設定する要素であると考えて良い。

表xx2: ノードタイプ一覧
B(Broadcast)ノードブロードキャストのみを用いて名前を解決
P(Point-to-Point)ノード NetBIOSネームサーバ(WINS)のみを用いて名前を解決
M(Mixed mode)ノード Bノード -> Pノードの順に名前を解決
H(Hybrid mode)ノード Pノード -> Bノードの順に名前を解決
この他LAN Manager の時代には、Bノード失敗後にLMHOSTS ファイルを参照する実装を「拡張Bノード」と称していたが, 現在のマイクロソフトの実装では, 上記4つすべてのノードにおいて名前解決に失敗すると, LMHOSTS を参照する実装に拡張されているため, 敢えてBノードの拡張に対してのみ特別な呼称を用いることに意味があるとは言えないと考える。

なおノードタイプ自体はRFC1001, RFC1002で定義されているが、定義されているのは最初の3つだけである。 通常利用されるのは、WINS環境でのデフォルトであるHノードか, WINS がない環境のデフォルトであるBノードであるが, HノードはRFCに定義されていないMicrosoftの独自仕様である。 ノードタイプはDHCPサーバの管理者がDHCPオプションとして指定する際に通常Hノードで指定するという以外では、 あまり意識することはないであろうが、トラヒックのチューニングの際には考慮しておいた方がよい。

WINS サーバへの名前問い合わせ

WINSサーバにはプライマリとセカンダリがある(注17.5)が、DNSとは異なり、プライマリのWINSサーバで名前解決に失敗した場合は、セカンダリのWINSサーバに問い合わせが行われる。 このため、セキュリティ上の具合などで、社員用 WINS サーバと派遣社員用WINS サーバを用意し、社員はプライマリに社員用、セカンダリに派遣社員用といった運用も可能である。

注17.5: Windows 95 にはセカンダリサーバの指定がないとプライマリサーバの指定が無効になるという 有名すぎるバグがある。WINS サーバがネットワークに1台しかない場合, Windows 95 クライアントにはプライマリ/セカンダリともに同じ WINS サーバを指定すること。

DNS/hosts ファイルによる名前解決

NetBIOS 名の解決にも関わらず、優先度は低いながらも hosts/DNS への問い合わせが可能になっている。 ただし、hosts/DNS で名前解決が可能なものは、CIFS と同様ファイルサーバを示す識別子 0x20 とドメインログオンに必要な各種 NetBIOS 名だけである(注18)。 この名前解決はダイアルアップ環境などでトラヒック増加の原因となるが, Windows 95/98 等ではデフォルトで有効になっているため, 利用していないのであれば無効にすることを推奨する。 詳細については Q137368: How to Disable NetBIOS Name Resolution on DNS を参照してほしい。

注18: DNS のみでドメインログオンを実装する方法に付いては J041750: Windows NT のドメインを認識する DNS の設定 を参照のこと

名前解決の手段の優先順位を変更する

Windows NT 4.0 や Windows 95/98 では、レジストリを変更することで、名前解決の手段の順番を変更することが可能である (注19)。しかしこの名前解決の順番は従来のMicrosoftネットワークの根幹を支えてきたものであるため、 この順番を変更した場合何が発生するかは予測がつかない。従って、筆者としては変更は絶対に行うべきでないとかんがえる。

注19: Q139270: How to Change Name Resolution Order on Windows 95 and Windows NT および関連する KB(Q170619, Q171567)を参照して頂きたい。

次回予告

ここまでNetBEUIからはじめて、Microsoftネットワークの仕様の拡張を、通信方式と名前解決を中心にして述べてきた。 何故Microsoftネットワークがこれほど複雑になったのかの一端をご理解頂ければ幸いである。 なお、ここに記述した内容は筆者が実験を行って確認したものであるが、 全てのサービスパックやOSバージョンについて検証を行ったものではないため、記述漏れや誤りがあるかも知れない。 その際は気軽にご指摘頂ければ幸いである。 次回はマイクロソフトネットワーク最大の難関であるブラウジングについて解説していきたい。

注記・補足

  1. 本文書は、日経オープンシステム 2000 年 9 月号の「オープンセミナー」に掲載された「Microsoft ネットワークを解剖する 第1回「NetBIOSでの通信と名前解決の仕組み」-- Microsoftネットワークの混迷 --」の草稿を有志の方に HTML 化していただき、掲載しているものです。
  2. 本連載を元にして、「アンドキュメンテッド Microsoft ネットワーク」を出版しておりますので、併せてご参照ください。

Copyright (C) 1998-2009 TAKAHASHI, Motonobu
Last update: 2006-07-12 00:00:19 JST
webmaster@monyo.com