00:56Windowsで使われる、NetBIOSまわりを頑張ってみます。やりたいことは、Windowsコンピュータ名(NETBIOS名)からIPアドレスを取得することです。NetBIOSはとにかく不可解です。本当に不可解なんですが、歴史的背景があるので仕方がありません。どのくらい古いかというと1980年代くらいなので仕様書もイマイチ読みづらく、後の改変も多数あるので本当にわかりづりです。NetBIOSはTCP/IPとは別物です。現在ではプロトコル部分をNetBEUI、インターフェイス部分をNetBIOSと呼ぶようですが、元はインターフェイス(API)からプロトコルまですべてひっくるめた規格でした。NetBEUIは現在では使われることは無くなりましたが、NetBIOSのインターフェイスだけは利用され続けているというわけです。(TCP/IPとか言いながらUDP/IPも多用します)これ時代もWindows3.x時代のものなので何かと理解しづらいです。Extensions[MS-NBTE]をまず見てみると名前解決についてはRFC1002を見るように書いてあります。RFC1002の内容は「NetBIOS-over-TCP」となっています。読んでみると・・・なんか意味不明・・ですががんばって読む。+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Bはブロードキャストフラグなので、1で固定みたいです。フラグ部分は0x0110。これがまだ何故??というやり方で頭に???浮かびっぱなしです。NETBIOS名は15文字です。本来は16文字でしたが、最後の1バイトを別の用途に割り当てたため15文字。15文字に満たない場合はスペース(0x20)で埋めます。Managerの仕様ではなくMicrosoftの拡張仕様です。0x00はクライアント、0x20がサーバサービスを示すようなのでここでは0x20が正解だと思われます。(実際にはどちらも名前登録されていて、反応もしてくれるので良いのですが)で、肝心のNETBIOS名の格納方法です。最初の1バイトは0x20を指定します。0x20=長さが32byteの意味で、NETBIOS名の場合は32byte固定と書いてあるので必ず0x20を指定。NEBIOS名+サフィックスの16byteを以下の手順で符号化して32Byteにします。最後にNULL(0x00)くっつけるので、長さを表す先頭の0x20と合わせて34byteになります。これがQUESTION_NAMEになります。NETBIOS名の符号化は、まず文字コードを4バイト単位にわけます。空白文字(0x20)であれば0x2と0x0です。0x0をA、0x1をB、0x2をC・・・という感じで文字を割り当てます。0x20であれば「CA」になります。NETBIOS名が「FRED」であれば「EGFCEFEECACACACACACACACACACACACA」になります。これをUDPでブロードキャストすれば該当ホストがレスポンスを返してくれます。iOSで1024番以下のポートをbindできるのか?とちょっと不安でしたが、やってみたら大丈夫でした。+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+TTLより前はリクエストと同じ。ARRAYにIPアドレスが入ります。(複数ある場合は複数入ります。パケットの送信アドレスを見るか、自分のネットワークマスクと較べてどれを利用するか決めます)実際には名前の解放パケットとかも飛んでくるようですが(それを見てキャッシュから削除する)、iOSでそれを監視し続けるのは非現実的なので無視します。Resolution)を使う必要があります。今回はIPv4だけでいいのでそっちはやりません。(そのくらいの知識がある人はIPアドレスでわかるでしょうし・・・)さて、これでコンピュータ名(NETBIOS名)を解決できるようになりました。なったところでどう使うかは悩ましいところなんですけどね。