/*
* (C) Copyright IBM Corp. 2011
*
* LICENSE: Eclipse Public License v1.0
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.ibm.gaiandb.clientseeker;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* Set of utility methods covering IP address related operations - anything from
* getting a list of local IP addresses to comparing addresses to see if they are in the
* same network.
*
* @author DavidBarker
*
*/
public class NetworkUtils {
// Use PROPRIETARY notice if class contains a main() method, otherwise use COPYRIGHT notice.
public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2011";
/** Reference to the local host address */
private static InetAddress localAddress = null;
static {
try {
/* initialise the local address reference */
localAddress = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
System.err.println("Failed to get local host details.");
}
}
/**
* Return all valid IP addresses for this local host.
* Note: List can include both IPv4 and IPv6 addresses.
*
* @return a list of addresses represented as string or null in the event of an error.
* @throws UnknownHostException If the localhost name cannot be resolved.
* @throws SocketException
*/
public static String[] getLocalAddressStrings() throws UnknownHostException, SocketException {
String[] localAddressStrings = null;
if (localAddress != null) {
InetAddress[] allMyAddresses = getLocalAddresses();
if (allMyAddresses != null) {
localAddressStrings = new String[allMyAddresses.length];
for (int y=0; y < allMyAddresses.length; y++) {
localAddressStrings[y] = allMyAddresses[y].getHostAddress();
}
}
}
return localAddressStrings;
}
/**
* Return all valid IP addresses for this local host.
* Note: List can include both IPv4 and IPv6 addresses.
*
* @return a list of InetAddress objects or null in the event of an error.
* @throws UnknownHostException If the localhost name cannot be resolved.
* @throws SocketException if an error occurs getting the list of local interfaces
*/
public static InetAddress[] getLocalAddresses() throws UnknownHostException, SocketException {
List<InetAddress> allMyAddresses = new ArrayList<InetAddress>();
if (localAddress != null) {
Enumeration<NetworkInterface> localInterfaces = getLocalInterfaces();
Enumeration<InetAddress> interfaceAddresses = null;
while (localInterfaces.hasMoreElements()) {
/* get the set of addresses for each interface */
interfaceAddresses = localInterfaces.nextElement().getInetAddresses();
while (interfaceAddresses.hasMoreElements()) {
allMyAddresses.add(interfaceAddresses.nextElement());
}
}
// allMyAddresses = InetAddress.getAllByName(localAddress.getHostName());
}
InetAddress[] addresses = allMyAddresses.toArray(new InetAddress[allMyAddresses.size()]);
return addresses;
}
/**
* Return the set of network interfaces for the local host.
*
* @return an enumeration of the interfaces or null otherwise.
* @throws SocketException if an error occurs getting the interface list.
*/
public static Enumeration<NetworkInterface> getLocalInterfaces() throws SocketException {
return NetworkInterface.getNetworkInterfaces();
}
/**
* Build a subnet mask using the specified network prefix length.
*
* @see getNetworkPrefixLength()
* @param networkPrefixLength the prefix indicating the subnet mask (typically 8, 16, or 24 for IPv4).
* @return a byte array containing the full subnet mask.
*/
public static byte[] buildSubNetMaskFromNetworkPrefix(short networkPrefixLength) {
int mask = 0xffffffff << (32 - networkPrefixLength);
int value = mask;
byte[] maskBytes = new byte[]{
(byte)(value >>> 24), (byte)(value >> 16 & 0xff), (byte)(value >> 8 & 0xff), (byte)(value & 0xff) };
return maskBytes;
}
/**
* Get the network prefix length (indicating the subnet mask) for the specified
* IP address.
*
* @param ipAddress the ip address for which the prefix should be identified.
* @return the network prefix length or 0 if not found.
* @throws UnknownHostException if the ip address specified cannot be resolved to the local host.
* @throws SocketException if an error occurs while attempting to identify the network prefix length.
*/
public static short getNetworkPrefixLength(byte[] ipAddress) throws SocketException, UnknownHostException {
short prefix = 0;
if (ipAddress != null) {
prefix = getNetworkPrefixLength(InetAddress.getByAddress(ipAddress));
}
return prefix;
}
/**
* Get the network prefix length (indicating the subnet mask) for the specified
* IP address.
*
* @param ipAddress the ip address for which the prefix should be identified
* @return the network prefix length or 0 if not found.
* @throws SocketException if an error occurs while attempting to identify the network prefix length.
*/
public static short getNetworkPrefixLength(InetAddress ipAddress) throws SocketException {
short prefix = 0;
if (ipAddress != null) {
java.net.NetworkInterface myInterface = java.net.NetworkInterface.getByInetAddress(ipAddress);
for (int x=0; x < myInterface.getInterfaceAddresses().size(); x++) {
/* matching address will start /<ip of localhost> */
if (myInterface.getInterfaceAddresses().get(x).getAddress().equals(ipAddress)) {
prefix = myInterface.getInterfaceAddresses().get(x).getNetworkPrefixLength();
break;
}
}
}
return prefix;
}
/**
* Compute the network address given the specified IP address and subnet mask.
* Useful for comparing two IP addresses to determine if they are within the same subnet.
*
* @param ipAddress
* @param subnetMask
* @return the computed network address or an empty byte array otherwise.
*/
public static byte[] computeNetworkAddressBytes(byte[] ipAddress, byte[] subnetMask) {
byte[] networkAddressBytes = new byte[4];
if (ipAddress != null && subnetMask != null) {
/* Compute network address by ANDing the ip address with the subnet mask */
for (int x=0; x < networkAddressBytes.length; x++) {
networkAddressBytes[x] = (byte)(ipAddress[x] & subnetMask[x]);
}
} else {
System.err.println("Cannot compute network address - one or more arguments are null.");
}
return networkAddressBytes;
}
/**
* Compute the network address given the specified IP address and subnet mask.
* Useful for comparing two IP addresses to determine if they are within the same subnet.
*
* @param ipAddress the IP address
* @param subnetMask the subnet mask
* @return the computed network address or null otherwise.
* @throws UnknownHostException if the computed network address cannot be resolved to a valid InetAddress
*/
public static InetAddress computeNetworkAddress(InetAddress ipAddress, byte[] subnetMask) throws UnknownHostException {
InetAddress networkAddress = null;
byte[] networkAddressBytes = computeNetworkAddressBytes(ipAddress.getAddress(), subnetMask);
networkAddress = InetAddress.getByAddress(networkAddressBytes);
return networkAddress;
}
}