コンピュータのIPアドレスを知りたかったら、Windowsなら設定の「ネットワークとインターネット→プロパティ」で簡単に表示できる。こうしたGUIによるIPアドレスの表示機能は、最近のOSであればたいてい持っている。

しかし、あなたがプログラムを作って、その中でIPアドレスを知りたいとき、GUIによる方法は使えない。なぜなら、あなたのプログラムは、設定ページを開くことはできても、そこに表示された内容を「見る」ことはできないからだ。スクリプトなら、OSの標準的なコマンドの出力を調べる方法がある。たとえば、“Get-NetIPAddress”(PowerShell)、ipconfig.exe(cmd.exe)など、Linuxなら“ip address”コマンドを利用することが可能だが、C言語などでプログラムを作る場合にはあまり向いていない方法だ。

一般的には、こういうとき、プログラムからは、API(Application Program Interface)と呼ばれる機能を使う。インターネット検索すると、WindowsのAPIの1種である.NET Frameworkでは、「Dns.GetHostAddresses」を使えばいいと主張するサイトが結構ある。これは、間違いではないが、正解ではない。実行してみれば、わかるが、得られるのはIPアドレスのみで、通常は複数のIPアドレスが返される。

筆者のマシンでは、15個のIPアドレスが返される。たしかにどれも、プログラムを実行しているマシンのIPアドレスだが、たとえば、仮想マシンとの接続に使われている仮想ネットワークアダプタ(Hyper-Vでは仮想スイッチという)のIPアドレスも含まれている。これは、IPアドレスには違いないが、仮想マシンとしか通信ができない。

Windowsの設定ページには、IPv6アドレス2つ(うち1つは、自動割り当てのリンクローカルアドレス)と、IPv4アドレス1つの3つのIPアドレスしか書いていない。APIが返す、その他のIPアドレスは、IPアドレスではあるが、ユーザーが必要としているIPアドレスではないのだ。コンピューターは、気を利かして人間が必要そうな情報を返すということはしない。聞かれたものを正直に答えるだけだ。ある意味、「聞き方」がわるいのである。

「Dns.GetHostAddresses」は、その時点で有効なIPアドレスを列挙するだけの機能しかない。これを使っていては、正解にはたどり着けない。まずは、何を知りたいのかを明確にする必要がある。たとえば、無線LANのIPアドレスなのか、イーサーネットのIPアドレスなのか? これを明確にしない限り、IPアドレスを選別することができない。

ではどうやったら正しいIPアドレスが得られるのかというと、動作しているネットワークインターフェース(イーサーネットや無線LANなどのハードウェア)を探す。これは、ネットワーク接続の有無にかかわらずいつでも列挙できる(複数見つかる可能性がある)。次に、このネットワークインターフェースから適切なものを探し、そのIPアドレスを調べるというのが正しいIPアドレスを得る手続きだ。

.NET Frameworkでは“NetworkInterface クラス”を使えば、すべてのネットワークの列挙が可能になる(写真01)。ここで、不要なもの(LoopbackやHyper-Vの仮想アダプタ、Bluetooth関連のもの)や動作していないものを落とせば、動作中のイーサーネットや無線LANなどが残る。そのうえでオブジェクトのプロパティやメソッドをたどって、インターフェースに割り当てられているIPアドレスを調べる。

写真01: PowerShellから.NETのNetworkInterfaceクラス(System.Net.NetworkInformation.NetworkInterface)のGetAllNetworkInterfaces()メソッドを使ってネットワークインターフェースを列挙させることができる。これはPowerShellの組み込みコマンドではなく、直接.NETを呼び出している

Linuxでは、このあたりは、もう少し簡単だ。というのは、ネットワークアダプターを始めシステムの多くの情報は、/sysファイルシステムの下に整理されているからだ(写真02)。/sys/devicesの下でネットワークデバイスを探す(複数存在する場合がある)。デバイス名がわかれば、ソケットを作りioctlでIPアドレスを調べることができる。

写真02: Linuxでは、/sysの下にさまざまなシステム情報がある。“/sys/devices”の下で“net”ディレクトリを探せば、そこにネットワークデバイス(ネットワークアダプタ)の情報がある。これでネットワークデバイスのデバイス名や情報を得ることが可能。デバイス名のディレクトリにあるテキストファイルなどを調べることでネットワークデバイスの種別や動作状態などを判定できる。プログラムからは、通常のファイル操作として実行できる

どの場合も、複数のIPアドレスが得られることがある。そこから先はIPアドレスに関する知識(たとえばIPv6のリンクローカルアドレスや匿名アドレスなど)を使って、不要なものを排除していく。

設定ページを見れば簡単にわかるIPアドレスだが、自分で作るプログラムがこれを得るのは簡単ではない。表示してるんだから、教えてくれてもいいじゃないか、と言いたくなるぐらいコンピュータは意地悪なのである。

今回のタイトルの元ネタは、映画「ロンゲスト・ヤード」(The Longest Yard,1974)の別タイトルである“The Mean Machine”(意地悪な機械)である。この映画、筆者が中学生ぐらいの頃に劇場公開されたもので、この別タイトルが、当時集めていたチラシにも記載されていて、なぜか記憶に残っている。ちなみに、そのチラシ、映画情報サイトIMDbで見ることができる。