简体   繁体   English

从给定的IP地址和子网掩码中获取所有IP地址

[英]Get all IP addresses from a given IP address and subnet mask

In Java, I need to get list of all IP Addresses contained by a given IP network. 在Java中,我需要获取给定IP网络包含的所有IP地址的列表。

For eg let the netowork be: 192.168.5.0/24 then the output will be (192.168.5.0 ... 192.168.5.255). 例如,让netowork为:192.168.5.0/24,那么输出将为(192.168.5.0 ... 192.168.5.255)。

I could think of the following way but it looks dirty, is there any elegant way? 我可以想到以下方式,但它看起来很脏, 有什么优雅的方式吗? There is no function for the same in InetAddress class. InetAddress类中没有相同的功能。

  1. Get Network Ip from the input Ip and subnet mask. 从输入Ip和子网掩码中获取Network Ip。

     mask = (long)(0xffffffff) << (32-subnetMask); Long netIp = getLongfromIp(Inputip)& mask; 

The function 'getLongfromIp' contains code from - How to convert string (IP numbers) to Integer in Java 函数'getLongfromIp'包含以下代码 - 如何在Java中将字符串(IP号)转换为Integer

  1. get the number of hosts by Subnet Mask 通过子网掩码获取主机数量

    maxRange = (long)0x1<<(32-subnetMask);

  2. Get address of all hopes by adding i for i in (0 .. maxRange) in the netIp 通过在netIp中添加i for i in (0 .. maxRange) maxRange for i in (0 .. maxRange)来获取所有希望的地址

  3. Convert the ip from above step to octet string. 将ip从上面的步骤转换为八位字符串。

Ps: I am sure the the IP Addresses will be in IPV4 only. Ps:我确定IP地址只能在IPV4中。

Answering my own question, solution is to use Apache commons.net library 回答我自己的问题,解决方案是使用Apache commons.net

import org.apache.commons.net.util.*;

SubnetUtils utils = new SubnetUtils("192.168.1.0/24");
String[] allIps = utils.getInfo().getAllAddresses();
//appIps will contain all the ip address in the subnet

Read more: Class SubnetUtils.SubnetInfo 阅读更多: Class SubnetUtils.SubnetInfo

To include NetworkAddress and BroadcastAddress 包括NetworkAddress和BroadcastAddress

import org.apache.commons.net.util.*;

 SubnetUtils utils = new SubnetUtils("192.168.1.0/28");
       utils.setInclusiveHostCount(true);

       String[] allIps = utils.getInfo().getAllAddresses();

The IPAddress Java library supports both IPv4 and IPv6 subnets in a polymorphic manner. IPAddress Java库以多态方式支持IPv4和IPv6子网。 Disclaimer: I am the project manager. 免责声明:我是项目经理。

Here is sample code to list the addresses for an IPv4 or Ipv6 subnet transparently. 以下是透明列出IPv4或Ipv6子网地址的示例代码。 Subnets can get quite large, especially with IPv6, and it is not wise to attempt to iterate through a large subnet, so the code for iterateEdges shows how to iterate through just the beginning and ending addresses in the subnet. 子网可能会变得非常大,特别是对于IPv6而言,尝试迭代大型子网并不明智,因此iterateEdges的代码显示了如何遍历子网中的开始和结束地址。

show("192.168.10.0/24");
show("2001:db8:abcd:0012::/64");

static void show(String subnet) throws AddressStringException {
    IPAddressString addrString = new IPAddressString(subnet);
    IPAddress addr = addrString.toAddress();
    show(addr);
    System.out.println();
}

static void show(IPAddress subnet) {
    Integer prefix = subnet.getNetworkPrefixLength();
    IPAddress mask = subnet.getNetwork().getNetworkMask(prefix, false);
    BigInteger count = subnet.getCount();
    System.out.println("Subnet of size " + count + " with prefix length " + prefix + " and mask " + mask);
    System.out.println("Subnet ranges from " + subnet.getLower() + " to " + subnet.getUpper());
    if(count.compareTo(BigInteger.valueOf(256)) <= 0) {
        iterateAll(subnet);
    } else {
        iterateEdges(subnet);
    }
}

static void iterateAll(IPAddress subnet) {
    BigInteger count = subnet.getCount();
    BigInteger three = BigInteger.valueOf(3), currentCount = count;
    int i = 0;
    for(IPAddress addr: subnet.getIterable()) {
        if(i < 3) {
            System.out.println(++i + ": " + addr);
        } else if(currentCount.compareTo(three) <= 0) {
            System.out.println(count.subtract(currentCount) + ": " + addr);
        } else if(i == 3) {
            System.out.println("...skipping...");
            i++;
        }
        currentCount = currentCount.subtract(BigInteger.ONE);
    }
}

static void iterateEdges(IPAddress subnet) {
    int sample = 3;
    for(int i = -sample; i < sample; i++) {
        if(i < 0) {
            int increment = i + sample + 1;
            System.out.println(increment + ": " + subnet.getLower().increment(increment - 1));
        } else {
            if(i == 0) {
                System.out.println("...skipping...");
            }
            BigInteger count = subnet.getCount();
            int increment = i - sample + 1;
            System.out.println(count.add(BigInteger.valueOf(increment)) + ": " + subnet.getUpper().increment(increment));
        } 
    }
}

Here is the output: 这是输出:

Subnet of size 256 with prefix length 24 and mask 255.255.255.0
Subnet ranges from 192.168.5.0/24 to 192.168.5.255/24
1: 192.168.5.0/24
2: 192.168.5.1/24
3: 192.168.5.2/24
...skipping...
253: 192.168.5.253/24
254: 192.168.5.254/24
255: 192.168.5.255/24

Subnet of size 18446744073709551616 with prefix length 64 and mask ffff:ffff:ffff:ffff::
Subnet ranges from 2001:db8:abcd:12::/64 to 2001:db8:abcd:12:ffff:ffff:ffff:ffff/64
1: 2001:db8:abcd:12::/64
2: 2001:db8:abcd:12::1/64
3: 2001:db8:abcd:12::2/64
...skipping...
18446744073709551614: 2001:db8:abcd:12:ffff:ffff:ffff:fffd/64
18446744073709551615: 2001:db8:abcd:12:ffff:ffff:ffff:fffe/64
18446744073709551616: 2001:db8:abcd:12:ffff:ffff:ffff:ffff/64

If you start with an address, then you can get the subnet using toPrefixBlock(): 如果您从一个地址开始,那么您可以使用toPrefixBlock()获取子网:

IPAddress addr = new IPAddressString("192.168.5.1/24").toAddress();
IPAddress subnet = addr.toPrefixBlock();
System.out.println(addr + " is from subnet " + subnet);

output: 输出:

192.168.5.1/24 is from subnet 192.168.5.0/24

The following is the same as Sean's (really nice!) answer using https://seancfoley.github.io/IPAddress/ , it is only reducing the signal to noise ratio: 以下与使用https://seancfoley.github.io/IPAddress/的 Sean(非常好!)答案相同,只是降低了信噪比:

subnetToIps("192.168.10.0/28");

    public void subnetToIps(String ipOrCidr) {
        IPAddressString addrString = new IPAddressString(ipOrCidr, IPAddressString.DEFAULT_VALIDATION_OPTIONS);
        IPAddress subnet = addrString.toAddress();
        System.out.println("Subnet ranges from " + subnet.getLower() + " to " + subnet.getUpper());

        int i = 0;
        for (IPAddress addr : subnet.getIterable()) {
            System.out.println(++i + ": " + addr);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM