読者です 読者をやめる 読者になる 読者になる

ネットワーク内の使用中ipとホスト名取得

Java ネットワーク

ipをきちんと管理していない環境で新規にコンピュータを追加するとき困ったので
ネットワーク内の使用中IPとホスト名取得が取得できないか調べていた。

そしたらJavaのInetAddressが使えそうだった。

  public void ipSearch(String ipAddress) {
    try {
      InetAddress ia;
      ia = InetAddress.getByName(ipAddress);
      boolean isAlive = ia.isReachable(searchTime);
      if (isAlive) {
        System.out.println("ip: " + ia.getHostAddress() + "  host name:"
            + ia.getHostName());
      }
    } catch (UnknownHostException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

これでipが使用中か、使用しているならホスト名が何かまでわかる。

ネットワークアドレス指定でネットワーク内の結果を確認できるようにしたかったので、
以下のようにした。

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class LanSerach {
  public static void main(String[] args) throws IOException {
    if (args.length < 1) {
      System.out.println("network address required");
      return;
    }
    IpSearch ipSearch = new IpSearch();
    ipSearch.search(args[0]);
  }

}

class IpSearch {
  static final int searchTime = 5000;

  public void search(String networkAddress){
    String[] networkAddressArray = networkAddress.split("/");
    if(networkAddressArray.length != 2){
      System.out.println("sample arugument: 192.168.11.0/24");
      return;
    }
    
    int mask = Integer.valueOf(networkAddressArray[1]);
    String[] byteString = networkAddressArray[0].split("\\.");
    if(byteString.length != 4){
      System.out.println("sample arugument: 192.168.11.0/24");
      return;
    }
    
    int[] netWorkAddress = new int[4];
    int[] hostAddress = new int[4];
    if(mask < 32){
      hostAddress[3] = 1;
    }
    int[] finalHost = new int[4];
    int maskPosi = 0;
    for(int i=0; i < 4; i++){
      int ipmask = 0;
      int fHost = 0;
      int k = 128;
      for(int j=0; j<8; j++){
        if(maskPosi < mask){
          ipmask += k;
          maskPosi++;
        }else{
          fHost += k;
        }
        k /= 2;
      }
      netWorkAddress[i] = Integer.valueOf(byteString[i]) & ipmask;
      finalHost[i] = fHost;
    }
    
    while(true){
      searchByAdapter(netWorkAddress[0] | hostAddress[0], 
          netWorkAddress[1] | hostAddress[1],
          netWorkAddress[2] | hostAddress[2], 
          netWorkAddress[3] | hostAddress[3] );
      if(!judgeHost(hostAddress, finalHost) || isBigger(hostAddress, finalHost)){
        return;
      }
      nextAddress(hostAddress);
    }
  }

  public boolean judgeHost(int[] hostAddress, int[] finalHost) {
    boolean ret = false;
    for (int i = 0; i < 4; i++) {
      if (hostAddress[i] != finalHost[i]) {
        ret = true;
        break;
      }
    }
    return ret;
  }

  public boolean isBigger(int[] hostAddress, int[] finalHost) {
    boolean ret = false;
    if (hostAddress[0] > finalHost[0]) {
      ret = true;
    } else if (hostAddress[0] == finalHost[0]) {
      if (hostAddress[1] > finalHost[1]) {
        ret = true;
      } else if (hostAddress[1] == finalHost[1]) {
        if (hostAddress[2] > finalHost[2]) {
          ret = true;
        } else if (hostAddress[2] == finalHost[2]) {
          if (hostAddress[3] > finalHost[3]) {
            ret = true;
          }
        }
      }
    }

    return ret;
  }

  public void nextAddress(int[] hostAddress) {
    if (hostAddress[3] < 254) {
      hostAddress[3]++;
    } else if (hostAddress[2] < 254) {
      hostAddress[2]++;
    } else if (hostAddress[1] < 254) {
      hostAddress[1]++;
    } else if (hostAddress[0] < 254) {
      hostAddress[0]++;
    }
  }

  public void searchByAdapter(int a, int b, int c, int d) {
    String val = String.valueOf(a) + "." + String.valueOf(b) + "."
        + String.valueOf(c) + "." + String.valueOf(d);
    ipSearch(val);
  }

  public void ipSearch(String ipAddress) {
    try {
      InetAddress ia;
      ia = InetAddress.getByName(ipAddress);
      boolean isAlive = ia.isReachable(searchTime);
      if (isAlive) {
        System.out.println("ip: " + ia.getHostAddress() + "  host name:"
            + ia.getHostName());
      }
    } catch (UnknownHostException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

これで、引数に"192.168.1.0/24"のように指定することでネットワーク内の
使用中ipが確認できるようになった。
アドレス周りの処理が汚いのでバグあるかも