LoginSignup
4
5

More than 5 years have passed since last update.

サブネットワークから欲しいIPアドレスを抽出

Posted at

commons-netのSubnetUtilsを使って、サブネットワークから欲しいIPアドレスを抽出するやり方。

例えば、「サブネットワークの先頭5個」「サブネットワークのうち、まだ使用されていないものの先頭1個」というケースを想定。

0. CIDR表記からインスタンス生成

javadocが下記の通り、丁寧に書いてあります。

public SubnetUtils(String cidrNotation)
Constructor that takes a CIDR-notation string, e.g. "192.168.0.1/16"

Parameters:
cidrNotation - A CIDR-notation string, e.g. "192.168.0.1/16"

Throws:
IllegalArgumentException - if the parameter is invalid, i.e. does not match n.n.n.n/m where n=1-3 decimal digits, m = 1-3 decimal digits in range 1-32

つまり、下記のようにしてインスタンスが生成できるということ。

SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");

subnet.getInfo() の戻り値のSubnetUtils.SubnetInfo から、ネットワークの情報を引き出せます。

1. ネットワークアドレス

getNetworkAddress()で取得できます。

SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
String networkAddress = subnet.getInfo().getNetworkAddress();
System.out.println(networkAddress);
192.168.0.0

2. ブロードキャストアドレス

getBroadcastAddress()で取得できます。

SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
String broadcastAddress= subnet.getInfo().getBroadcastAddress();
System.out.println(broadcastAddress);
192.168.0.255

3. その他のアドレス

getAllAddresses()で、使用できるアドレスを配列で取得できます。

SubnetUtils subnet = new SubnetUtils("192.168.0.0/30");
List<String> allAddresses= Arrays.asList(subnet.getInfo().getAllAddresses());
System.out.println(addAddresses);
[192.168.0.1,192.168.0.2]

4. アドレスの抽出

例1 サブネットワークの先頭5個

getAllAddresses()とsubListを組み合わせます。

SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
List<String> addresses= Arrays.asList(subnet.getInfo().getAllAddresses()).subList(0, 5);
System.out.println(addresses);

例2 サブネットワークのうち、まだ使用されていないものの先頭1個

使用済みのIPアドレスはDBから取得できるものとします。
コレクション操作のためにGuava を使います。(java7の仕事のときに編み出したので)

final List<String> usedAddresses = ...; //DBなどから取得
List<String> allAddresses= Arrays.asList(subnet.getInfo().getAllAddresses());

Predicate<String> isUnused = new Predicate<String>() {
   public boolean apply(String address) {
          return !usedAddresses.contains(address);
   }
};

String unusedAddress = Iterables.find(allAddresses, isUnused, "");

まとめ

サブネットのアドレス全体を配列で取得できるので、除外したいものをリストで取得できれば、大抵の抽出はできそう。
車輪の再発明する気がないなら、このあたりを使うと楽。

java8なら、streamとlambda式でもう少しすっきり書けるはず。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5