package eu.irreality.age.util.networking;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.StringTokenizer;
/**
* Workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037
* To obtain an external local inet address, rather than the loopback address, under linux.
* @author carlos
*
*/
public class LocalIPObtainer {
public static InetAddress askForIpAbroad()
{
try
{
URL whatismyip = new URL("http://automation.whatismyip.com/n09230945.asp");
BufferedReader in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine(); //you get the IP as a String
//System.out.println(ip);
return InetAddress.getByName(ip);
}
catch ( Exception e )
{
System.err.println("Could not ask for external IP address.\n");
e.printStackTrace();
return null;
}
}
public static String longToIpV4(long longIp) {
int octet3 = (int) ((longIp >> 24) % 256);
int octet2 = (int) ((longIp >> 16) % 256);
int octet1 = (int) ((longIp >> 8) % 256);
int octet0 = (int) ((longIp) % 256);
return octet3 + "." + octet2 + "." + octet1 + "." + octet0;
}
public static long ipV4ToLong(String ip) {
String[] octets = ip.split("\\.");
return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16) +
(Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]);
}
public static boolean isIPv4Private(String ip)
{
long longIp = ipV4ToLong(ip);
return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255")) ||
(longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255")) ||
longIp >= ipV4ToLong("192.168.0.0") && longIp <= ipV4ToLong("192.168.255.255");
}
public static boolean isIPv4Private ( InetAddress ip )
{
StringTokenizer st = new StringTokenizer(ip.toString(),"/");
System.err.println("Analysing " + ip);
if ( !ip.toString().startsWith("/") && st.hasMoreTokens() ) st.nextToken();
if ( st.hasMoreTokens() )
{
try
{
String candidate = st.nextToken();
System.err.println("Cand: " + candidate + ": " + isIPv4Private ( candidate ));
return isIPv4Private ( candidate );
}
catch ( Exception exc )
{
exc.printStackTrace();
return false;
}
}
else return false;
}
/**
* Returns an InetAddress representing the address
of the localhost.
* Every attempt is made to find an address for this
host that is not
* the loopback address. If no other address can
be found, the
* loopback will be returned.
*
* @return InetAddress - the address of localhost
* @throws UnknownHostException - if there is a
problem determing the address
*/
public static InetAddress getLocalHost() throws
UnknownHostException {
InetAddress localHost =
InetAddress.getLocalHost();
if(!localHost.isLoopbackAddress() && !localHost.isLinkLocalAddress() && !isIPv4Private(localHost)) return
localHost;
InetAddress[] addrs =
getAllLocalUsingNetworkInterface();
for(int i=0; i<addrs.length; i++) {
System.err.println("Obtained " + addrs[i]);
if( !addrs[i].isLoopbackAddress() && !addrs[i].isLinkLocalAddress() && !isIPv4Private(addrs[i]) ) //modified so it doesn't return lan addresses (192.168...) either.
return addrs[i];
}
return localHost;
}
/**
* This method attempts to find all InetAddresses
for this machine in a
* conventional way (via InetAddress). If only one
address is found
* and it is the loopback, an attempt is made to
determine the addresses
* for this machine using NetworkInterface.
*
* @return InetAddress[] - all addresses assigned to
the local machine
* @throws UnknownHostException - if there is a
problem determining addresses
*/
public static InetAddress[] getAllLocal() throws
UnknownHostException {
InetAddress[] iAddresses =
InetAddress.getAllByName("127.0.0.1");
if(iAddresses.length != 1) return
iAddresses;
if(!iAddresses[0].isLoopbackAddress())
return iAddresses;
return getAllLocalUsingNetworkInterface();
}
/**
* Utility method that delegates to the methods of
NetworkInterface to
* determine addresses for this machine.
*
* @return InetAddress[] - all addresses found from
the NetworkInterfaces
* @throws UnknownHostException - if there is a
problem determining addresses
*/
private static InetAddress[]
getAllLocalUsingNetworkInterface() throws
UnknownHostException {
ArrayList addresses = new ArrayList();
Enumeration e = null;
try {
e =
NetworkInterface.getNetworkInterfaces();
} catch (SocketException ex) {
throw new UnknownHostException
("127.0.0.1");
}
while(e.hasMoreElements()) {
NetworkInterface ni =
(NetworkInterface)e.nextElement();
for(Enumeration e2 =
ni.getInetAddresses(); e2.hasMoreElements();) {
addresses.add
(e2.nextElement());
}
}
InetAddress[] iAddresses = new
InetAddress[addresses.size()];
for(int i=0; i<iAddresses.length; i++) {
iAddresses[i] = (InetAddress)
addresses.get(i);
}
return iAddresses;
}
}