ネットワーク上の機器のIPアドレスを調べる方法

# 序

インターネット上のサーバーには、例えば https://www.kantei.go.jp/ とブラウザに入力すれば、アクセスすることができます。これはDNSサーバーに www.kantei.go.jp のIPアドレスが登録されているからなのはご存知のとおりです。ではもっとローカルなネットワーク、例えば会社のイントラネット上のサーバーのIPアドレスを調べることができるかと言えば、それは状況によってことなります。社内のDNSサーバーに登録されているサーバーなら話は簡単ですが、そうでないサーバーも多数あります。この記事では、そういったサーバーのIPアドレスを調べるテクニックを紹介します

# 基本的な考え方

- 調べたい機器について、何らかの情報（ホスト名であったり、MACアドレスであったり）を知っていて、それをもとにIPアドレスを調べます
- どの方法も絶対に調べられるというわけではありません
- 特に最近はOS上でfirewallが動作していることが多いので、その場合、外からそのホストの情報を得ることは困難です
- コマンド例はすべてwindowsのものです。

#  arpを使った方法

arpコマンドを使うと、同じサブネット内（同一セグメント内）の機器について、MACアドレスからIPアドレスを調べることができます。

## その１ ブロードキャストping

```
$ ping -n 1 -w 1000 ブロードキャストアドレス
$ arp -a
```
- 補足
  - ここでブロードキャストアドレスとは、自分が属しているネットワークが192.168.1.0/24なら192.168.1.255がブロードキャストになります。
  - pingの-n 1は1回だけpingを発行する、-w 1000は1秒待つという意味です
  - linuxの場合は、arp -nでarpテーブルの表示ができます

- 仕組み
  - 最初のpingで、対象の機器が返事を返してくれれば、自ホストのARPテーブルにMACアドレスとIPアドレスの対応が記憶されるので、arp -aで表示して確認することができます
  - ただしPC系のOSは、ブロードキャストpingに反応しないことが多いので調べられる機器が限定されます

## その2 手動ブロードキャストping

```
$ ping 192.168.1.1
$ ping 192.168.1.2
$ ...
$ ping 192.168.1.254
$ arp -a
```
- 補足
    - 自分が属しているネットワークが192.168.1.0/24とすると、最初のpingは同じネットワーク内のすべてのIPアドレスにpingを発行します
- 仕組み
    - 考え方はその1と同じですが、ブロードキャストpingに反応しないホストでも、個別pingには反応することは多いので、より汎用的に使えます
    - pingでなくてもスクリプト言語を使ってUDPパケットを送るだけでもいいです
        - 単純なUDPパケットの方が待ち合わせを調整できて楽です

## メリット・デメリット

- メリット
    - 特定のアプリケーションプロトコルに依存しない汎用性
    - 元情報となるMACアドレスの安定性
- デメリット
    - arpの仕組み上、セグメントを超えられない
    - 手動ブロードキャストはクラスB以上のネットワークだとあまり現実的でない
        - 特にAutoIPの自動割当にはクラスBネットワークが使われます
    - MACアドレスは覚えずらい

# nbtstatを使った方法

相手がwindowsならこの方法が有効です

## その1 同一セグメント内用

```
$ nbtstat -a コンピュータ名
$ nbtstat -c
```

- 仕組み
    - 相手がwindows（あるいはsambaを動かしたLinuxなど）なら、``nbtstat -a コンピュータ名``でセグメント内から見つけてくれます
    - nbtstat -cをすると、nbtテーブルにキャッシュされたIPアドレスの情報が表示されます
    - エクスプローラのアドレスバーに「\\\\コンピュータ名」と打った時と同じ仕組みです
    - linuxの場合は、``nmblookup コンピュータ名`` で調べられます
        - nmblookupはsambaに含まれます
        - IPアドレスも表示されます

## その2 セグメント越え

```
$ nbtstat -A 192.168.5.1
$ nbtstat -A 192.168.5.2
...
```
- 補足
    - 調査対象機器が、ネットワーク 192.168.5.0/24 に所属している場合の例です
- 仕組み
    - 調査対象の機器のネットワークアドレスが分かっているなら、IPアドレスを端から調べることができます
    - 個々の呼び出しが成功すれば、コンピュータ名が表示されるので、IPアドレスが確定します
    - Linuxの場合は、 ``nmblookup -A IPアドレス`` で調べられます

## メリット・デメリット

- メリット
    - 対象がwindowsで、同一セグメント内なら、非常によく機能する
- デメリット
    - windows以外にはあまり使えない
    - セグメント越えはネットワーク負荷もかかるので、ほどほどにしておいた方がよい


# mdnsを使った方法

同一セグメント内のPCに有効です

```
$ Resolve-DnsName コンピュータ名
または
$ Resolve-DnsName コンピュータ名.local
```
- 補足
    - 上記はPowerShell
- 仕組み
    - mdnsは同一セグメント内の名前解決をするためのプロトコルです
    - 特定プラットフォームに依存しないオープンな仕様です
    - 相手がhttpサーバーならブラウザに http://コンピュータ名.local でアクセスできます
    - linuxの場合は、 ``getent ahosts コンピュータ名.local`` で調べられます

## メリット・デメリット

- メリット
    - 最近のPCのOS（Windows、各種Linuxディストリビューション、MacOS）なら大体対応しています
- デメリット
    - スマホ・タブレット系は苦手です
        - androidは非対応（ずいぶん前から要求はされている）
        - chomeosもデフォルトでは非対応
        - iOSはクライアントとしては対応している（クエリーされても返事はしない）
        - その他、プリンタなどの対応状況は不明
    - セグメントを超えられない
        - 中継サーバーなどを立てれば、超えられる
       

# sshを使った方法

主に相手がLinuxの場合に有効です

```java
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.ConnectionInfo;

    public static ConnectionInfo getConnectionInfo(String hostName) throws IOException {
        Connection conn = new Connection(hostName);
        ConnectionInfo info = conn.connect();
        conn.close();
        return info;
    }
```

- 補足
    -  上記はjavaのganymed-ssh2を使ったコードです
    -  info.serverHostKeyでhostName（IPアドレスでもよい）で指定されたサーバーの、sshサーバー公開鍵が手に入ります
    -  sshコマンドで同じことをやれるかは調べていません
- 仕組み
    -  事前に調査対象のsshサーバーの公開鍵をもっておきます
    -  上記のgetConnectionInfoのhostNameにIPアドレスを指定して、sshサーバー公開鍵を手に入れます
    -  2つの公開鍵が同一ならIPアドレス確定、違っていれば別のIPアドレスを試す

- メリット
    - sshサーバーさえ立っていれば使えるので、ある程度の汎用性があります。特にLinuxに対して有効です
    - sshプロトコルベースなので、セグメントを超えられます
- デメリット
    - 片っ端から調べる系なので、ネットワーク負荷は大きいです


# まとめ

- 同一セグメント内ならmDNSが割と幅広く使えると思います
    - ただしスマホ・タブレットを含めるとなると厳しいです
- arpはプロトコル自体はどの機器でも使えるのが魅力だけど、ブロードキャストpingに反応しない機器が多いのが残念です
- 上記以外に使えそうなプロトコルがあったら教えてください