Skip to content

Instantly share code, notes, and snippets.

@ssttevee
Last active June 30, 2023 14:11
Show Gist options
  • Select an option

  • Save ssttevee/b0e2b431f4b23d289537 to your computer and use it in GitHub Desktop.

Select an option

Save ssttevee/b0e2b431f4b23d289537 to your computer and use it in GitHub Desktop.
List all possible IP addresses in a given subnet. Should work with both IPv4 and IPv6
import java.net.*;
import java.util.*;
public class SubnetAddresses {
public static void main(String[] args) throws UnknownHostException, SocketException {
// get all possible IP addresses of all LANs
Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
while (nis.hasMoreElements()) {
// Get the next network interface
NetworkInterface ni = nis.nextElement();
// We only want LANs
// loopback infers that it is not a LAN
if (ni.isLoopback()) continue;
// Iterate through the addresses attached to the network interface
for (InterfaceAddress ia : ni.getInterfaceAddresses()) {
List<byte[]> addresses = getAllAddresses(ia.getAddress().getAddress(), ia.getNetworkPrefixLength());
// Sort addresses
Collections.sort(addresses, new AddressComparator());
// Output addresses to console
for (byte[] address : addresses) System.out.println(InetAddress.getByAddress(address));
}
}
}
/**
* Creates a list of all possible IP addresses in a subnet given an IP address and the network mask
* @param address IP address in byte array form (i.e. 127.0.0.1 = 01111111 00000000 00000000 00000001)
* @param maskLength Network mask length (i.e. the number after the forward-slash, '/', in CIDR notation)
* @return All possible IP addresses
*/
public static List<byte[]> getAllAddresses(byte[] address, int maskLength) {
return getAllAddresses(address, maskLength, true);
}
/**
* Recursively calculate each IP address within a subnet
* @param address IP address in byte array form (i.e. 127.0.0.1 = 01111111 00000000 00000000 00000001)
* @param maskLength Network mask length (i.e. the number after the forward-slash, '/', in CIDR notation)
* @param scrub Whether or not to scrub the unmasked bits of the address
* @return All possible IP addresses
*/
private static List<byte[]> getAllAddresses(byte[] address, int maskLength, boolean scrub) {
if (scrub) scrubAddress(address, maskLength);
// logAddress(address);
if (maskLength >= address.length * 8) return Collections.singletonList(address);
List<byte[]> addresses = new ArrayList<byte[]>();
int set = maskLength / 8;
int pos = maskLength % 8;
byte[] addressLeft = address.clone();
addressLeft[set] |= 1 << pos;
addresses.addAll(getAllAddresses(addressLeft, maskLength + 1, false));
byte[] addressRight = address.clone();
addressRight[set] &= ~(1 << pos);
addresses.addAll(getAllAddresses(addressRight, maskLength + 1, false));
return addresses;
}
/**
* Set the unmasked bits of the IP address to 0
* @param address IP address in byte array form (i.e. 127.0.0.1 = 01111111 00000000 00000000 00000001)
* @param maskLength Network mask length (i.e. the number after the forward-slash, '/', in CIDR notation)
* @return The scrubbed IP address
*/
private static byte[] scrubAddress(byte[] address, int maskLength) {
for (int i = 0; i < address.length * 8; i++) {
if (i < maskLength) continue;
address[i / 8] &= ~(1 << (i % 8));
}
return address;
}
/**
* Output the IP address to the console, first in dotted-decimal notation, then in byte array form
* <br><br>
* i.e.<br>
* 127.0.0.1<br>
* 01111111 00000000 00000000 00000001
*
* @param address IP address in byte array form (i.e. 127.0.0.1 = 01111111 00000000 00000000 00000001)
*/
public static void logAddress(byte[] address) {
String addressInts = "";
String addressBits = "";
for (byte octet : address) {
addressInts += String.valueOf((int) octet & 0xFF);
addressInts += ".";
for (int i = 7; i >= 0; i--) {
int bit = 1 << i;
addressBits += String.valueOf((octet & bit) == bit ? "1" : "0");
}
addressBits += " ";
}
System.out.println(addressInts.substring(0, addressInts.length() - 1));
System.out.println(addressBits.substring(0, addressBits.length() - 1));
}
/**
* Comparator to compare IP addresses that are in byte array form
*/
public static class AddressComparator implements Comparator<byte[]> {
@Override
public int compare(byte[] lhs, byte[] rhs) {
if (lhs.length != rhs.length) return lhs.length < rhs.length ? -1 : 1;
int pos = lhs.length - 1;
while (lhs[pos] == rhs[pos]) {
if (--pos < 0) return 0;
}
return (lhs[pos] & 0xFF) < (rhs[pos] & 0xFF) ? -1 : 1;
}
}
}
@pitester12

Copy link
Copy Markdown

God that is so complicated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment