Сетевые вычисления IPv4 / IPv6 и проверка для Java? - PullRequest
9 голосов
/ 17 февраля 2009

Я ищу пакет, похожий на Net_IPv4 и Net_IPv6 , но написанный для Java. Это должно быть в состоянии сделать следующее:

  • Убедитесь, что адрес действителен (например, 127.0.0.1 действителен, 127.0.0.257 - нет)
  • Возврат, если адрес содержится в подсети (например, 127.0.0.11 в 127.0.0.0/28)
  • Возвращает широковещательный адрес для данной подсети (например, для 127.0.0.0/28 это 127.0.0.15)

Было бы замечательно, если бы это также могло быть:

  • Возвращает список адресов для подсети в порядке
  • Сортировка списка адресов

Возможно, я мог бы написать пакет, чтобы сделать все это, но если кто-то уже прошел через проблему и, скорее всего, сделал лучшую работу, я полностью использую это. Кто-нибудь знает такой пакет или пакеты, которые могли бы сделать все это? Мы расширяемся до IPv6, поэтому он должен работать как для IPv4, так и для IPv6, если это возможно.

Я ценю любую помощь.

Ответы [ 5 ]

6 голосов
/ 18 февраля 2009

Это только для IPv4, но класс SubnetUtils , входящий в Commons Net , обладает нужной вам функциональностью. Исходя из этого, вы можете кодировать версию IPv6 и вносить ее обратно в проект! :)

5 голосов
/ 23 февраля 2013

Может быть CIDRUtils может помочь вам. Это позволяет преобразовывать нотацию CIDR в диапазон IP-адресов.

Отказ от ответственности: я являюсь автором CIDRUtils.

3 голосов
/ 07 апреля 2015

Я основной участник commons-ip-math , библиотеки Java с открытым исходным кодом, которая предлагает богатый API для работы с наиболее распространенными вычислениями IPv4, IPv6 и AS. Хотя он только недавно был открыт с открытым исходным кодом, он годами испытывался в боевых условиях RIPE NCC . Посмотрите, как вы можете использовать его ниже.

(Все примеры работают с одинаковым синтаксисом для номеров IPv6 и AS. Просто используйте вместо этого классы Ipv6, Ipv6Range, Asn и AsnRange).

  • Убедитесь, что адрес действителен (например, 127.0.0.1 действителен, 127.0.0.257 - нет)
Ipv4.parse("127.0.0.1");     // IPv4 representation of "127.0.0.1"
Ipv4.parse("127.0.0.257");   // IllegalArgumentException
  • Возврат, если адрес содержится в подсети (например, 127.0.0.11 в 127.0.0.0/28)
Ipv4Range.parse("127.0.0.0/28").contains(Ipv4.parse("127.0.0.11"));  //true  
  • Возвращает широковещательный адрес для данной подсети (например, для 127.0.0.0/28 это 127.0.0.15)
Ipv4Range.parse("127.0.0.0/28").start().upperBoundForPrefix(28)  // 127.0.0.15
  • Возвращает список адресов для подсети в порядке
// Range types are Iterable
for (Ipv4 ipv4 : Ipv4Range.parse("127.0.0.0/30")) {
  System.out.println(ipv4);
}
// Will print:
127.0.0.0
127.0.0.1
127.0.0.2
127.0.0.3
  • Сортировать список адресов

Хотя библиотека предлагает компараторы для типов диапазонов (например, сравнивая размер подсетей), компаратора для отдельных адресов не существует. Однако написать свой собственный довольно тривиально, так как типы Ipv4, IPv6 и ASN реализуют интерфейс Comparable:

List<Ipv4> list = new ArrayList<Ipv4>();
list.add(Ipv4.of("0.0.0.3"));
list.add(Ipv4.of("0.0.0.4"));
list.add(Ipv4.of("0.0.0.2"));
list.add(Ipv4.of("0.0.0.1"));
Collections.sort(list, new Comparator<Ipv4>() {
    @Override
    public int compare(Ipv4 left, Ipv4 right) {
        return left.compareTo(right);
    }
});
System.out.println(list);
// Will print:
[0.0.0.1, 0.0.0.2, 0.0.0.3, 0.0.0.4]
2 голосов
/ 17 октября 2016

Java-библиотека IPAddress поддерживает как IPv4, так и IPv6 полиморфным образом, включая подсети. Javadoc доступен по ссылке. Отказ от ответственности: я менеджер проекта.

Все перечисленные варианты использования прозрачно поддерживаются как для IPv4, так и для Ipv6. Другими словами, он отличается от большинства других утилит в том смысле, что приведенный ниже код работает идентично с IPv4 или IPv6 в качестве входных строк.

Убедитесь, что адрес действителен

    String str = "::1";
    IPAddressString addrString = new IPAddressString(str);
    try {
         IPAddress addr = addrString.toAddress();
         ...
    } catch(IPAddressStringException e) {
        //e.getMessage provides validation issue
    }

Возврат, если адрес содержится в подсети

    String str = "1::1";
    String subnetStr = "1::/64";
    IPAddressString addrString = new IPAddressString(str);
    IPAddressString subnetString = new IPAddressString(subnetStr);
    try {
         IPAddress addr = addrString.toAddress();
         IPAddress subnet = subnetString.toAddress();
         boolean isContained = subnet.contains(addr); //true in this case
         ...
    } catch(IPAddressStringException e) {
        //e.getMessage provides validation issue
    }

Возвращает широковещательный адрес для данной подсети

    String subnet = "127.0.0.0/28";
    IPAddressString subnetString = new IPAddressString(subnet);
    try {
         IPAddress subnet = subnetString.toAddress();
         IPAddress broadcastAddr = subnet.getHighest();
         ...
    } catch(IPAddressStringException e) {
        //e.getMessage provides validation issue
    }

Возвращает список адресов для подсети в порядке

    String subnet = "127.0.0.0/28";
    IPAddressString subnetString = new IPAddressString(subnet);
    try {
         IPAddress subnet = subnetString.toAddress();
         for(IPAddress addr : subnet) {
             ...
         }
    } catch(IPAddressStringException e) {
        //e.getMessage provides validation issue
    }

Сортировка списка адресов

    List<IPAddressString> addrs; 
    Collections.sort(addrs); //IPAddressString implements Comparable

Получить набор сетей подсетей и список адресов (ответ на AhmedRana):

    IPAddress subnet = new IPAddressString("192.168.0.0/28").getAddress();
    IPAddress newSubnets = subnet.adjustPrefixLength(1, false);
    System.out.println(newSubnets); //192.168.0.0-8/29
    HashSet<IPAddress> subnetSet = new HashSet<IPAddress>();
    ArrayList<IPAddress> addrList = new ArrayList<IPAddress>();
    for(IPAddress addr : newSubnets.getIterable()) {
        subnetSet.add(addr.toPrefixBlock());
        addrList.add(addr);
    }
    System.out.println(subnetSet);//[192.168.0.0/29, 192.168.0.8/29]

    System.out.println(addrList);
                //[192.168.0.0/29, 192.168.0.1/29, 192.168.0.2/29,
                //192.168.0.3/29, 192.168.0.4/29, 192.168.0.5/29,
                //192.168.0.6/29, 192.168.0.7/29, 192.168.0.8/29,
                //192.168.0.9/29, 192.168.0.10/29, 192.168.0.11/29,
                //192.168.0.12/29, 192.168.0.13/29, 192.168.0.14/29,
                //192.168.0.15/29]

Может быть много адресов. Более эффективный способ получить новый список подсетей - использовать итератор префиксного блока, который перебирает подсети префиксного блока, как показано ниже:

    IPAddress subnet = new IPAddressString("192.168.0.0/28").getAddress();
    IPAddress newSubnets = subnet.adjustPrefixLength(1, false);
    System.out.println(newSubnets); // 192.168.0.0-8/29
    Iterator<? extends IPAddress> iterator = newSubnets.prefixBlockIterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
    }
    // 192.168.0.0/29
    // 192.168.0.8/29
0 голосов
/ 18 февраля 2009

Класс InetAddress и связанные с ним подклассы были бы очень хорошим местом для начала: http://java.sun.com/j2se/1.4.2/docs/api/java/net/InetAddress.html

...