package net.java.sip.communicator.impl.netaddr;
import java.net.*;
/**
* An entry in the Address Pool. An addresspool entry contains an address
* belonging to any of the local network interfaces together with properties
* that characterize them, such as - whether or not the address is publicly
* routable or not, It's corresponding NAT entry obtained by stun. The type of
* NAT that the address is located behind (if any). The lifetime of the bindings
* behind this NAT. Any TURN bindings. Whether or not TCP connections seem to be
* supported. Whether or not UDP connections seem to be supported, and etc. etc.
*
* Concerning the address, this is an immutable object, in other words, the
* address of a single entry is not supposed to change once it has been created.
* In case this address is modified while the application is running we'll
* rather have a new address entry instead of modifying this one. The only thing
* that can change about an address pool entry is its properties.
*
* @author Emil Ivov
*/
public class AddressPoolEntry
{
private InetAddress address = null;
/**
* The AddressPreference qualifyer is used to indicate preference of this
* address compared to others available on the current host.
*/
private AddressPreference preference;
/**
* Only used for ipv4 addresses. Actually it would have been better to use
* the isLinkLocal method of InetAddress but since it only works for ipv6
* we're using this one. in the case of an ip address
*/
private boolean isLinkLocal = false;
private NetworkInterface ownerInterface = null;
private FirewallDescriptor firewallDescriptor = null;
private InetAddress turnAddress = null;
public AddressPoolEntry(InetAddress address, NetworkInterface ownerIface)
{
if(address == null)
throw new NullPointerException("Address param cannot be null");
this.address = address;
this.ownerInterface = ownerIface;
}
/**
* Returns the ip address that this address pool entry represents.
* @return InetAddress
*/
public InetAddress getInetAddress()
{
return address;
}
/**
* Determines whether or not the address pool entry represents an IPv6
* address.
* @return true if the address is ipv6 and false in case of ipv4.
*/
public boolean isIPv6()
{
return (address instanceof Inet6Address);
}
/**
* Determines whether this is a link local or publicly routable address.
* Works for both IPv4 and IPv6 addresses.
* @return true if the address is link local and thus not globally routable
* and false if otherwise.
*/
public boolean isLinkLocal()
{
if( address instanceof Inet6Address){
if(address.isLinkLocalAddress()){
return true;
}
else{
return false;
}
}
return isLinkLocal;
}
/**
* Specifies whether or not the address is an IPv4 link local address.
* @param linkLocal true if t
*/
void setLinkLocal(boolean linkLocal)
{
this.isLinkLocal = linkLocal;
}
/**
* Determines whether the address is the result of windows auto configuration.
* (i.e. One that is in the 169.254.0.0 network)
* @param add the address to inspect
* @return true if the address is autoconfigured by windows, false otherwise.
*/
/**
* Determines whether the address is the result of windows auto configuration.
* (i.e. One that is in the 169.254.0.0 network)
* @param add the address to inspect
* @return true if the address is autoconfigured by windows, false otherwise.
*/
public static boolean isIPv4LinkLocalAutoconf(InetAddress add)
{
return (add.getAddress()[0] & 0xFF) == 169
&& (add.getAddress()[1] & 0xFF) == 254;
}
/**
* Determines whether the address encapsulated by this entry is the result of
* windows auto configuration (i.e. One that is in the 169.254.0.0 network)
* @return true if the address is autoconfigured by windows, false otherwise.
*/
public boolean isIPv4LinkLocalAutoconf()
{
return isIPv4LinkLocalAutoconf(address);
}
/**
* Determines whether the address is an IPv4 link local address. IPv4 link
* local addresses are those in the following networks:
*
* 10.0.0.0 to 10.255.255.255
* 172.16.0.0 to 172.31.255.255
* 192.168.0.0 to 192.168.255.255
*
* @param add the address to inspect
* @return true if add is a link local ipv4 address and false if not.
*/
public static boolean isLinkLocalIPv4Address(InetAddress add)
{
if(add instanceof Inet4Address)
{
byte address[] = add.getAddress();
if ( (address[0] & 0xFF) == 10)
return true;
if ( (address[0] & 0xFF) == 172
&& (address[1] & 0xFF) >= 16 && address[1] <= 31)
return true;
if ( (address[0] & 0xFF) == 192
&& (address[1] & 0xFF) == 168)
return true;
return false;
}
return false;
}
/**
* Determines whether the address encapsulated by this entry is an IPv4 link
* local address. IPv4 link local addresses are those in the following
* networks:
*
* 10.0.0.0 to 10.255.255.255
* 172.16.0.0 to 172.31.255.255
* 192.168.0.0 to 192.168.255.255
*
* @return true if add is a link local ipv4 address and false if not.
*/
public boolean isLinkLocalIPv4Address()
{
return isLinkLocalIPv4Address(this.address);
}
/**
* Determines whether the address encapsulated by this entry is an IPv6 link
* local address. IPv6 link local addresses are briefly those that start
* with fe80.
*
* @return true if add is a link local ipv6 address and false if not.
*/
public boolean isLinkLocalIPv6Address()
{
return address instanceof Inet6Address && address.isLinkLocalAddress();
}
/**
* Determines whether this is the localhost address (127.0.0.1 or ::1).
* This is a simple wrapper of the InetAddress.isLoopbackAddress() method.
* @return true if this is and IPv6 or IPv4 loopback address and false
* otherwise.
*/
public boolean isLoopback()
{
return address.isLoopbackAddress();
}
/**
* Determines whether the adderss encapsulated by this address entry is
* a globally routable inet address, or in other words is it possible
* (at least in theory) to directly send packets to it from any point of
* the internet.
* @return true if this is a public ip addr and false otherwise.
*/
public boolean isGloballyRoutable()
{
return !isLinkLocalIPv6Address()
&& !isIPv4LinkLocalAutoconf()
&& !isLinkLocalIPv4Address()
&& !isLoopback();
}
/**
* Determines whether the adderss encapsulated by this address entry is
* a 6to4 translation address (2002::/16)
*
* @return true if this is a 6to4 ip addr (belongs to 2002::/16) and false
* otherwise.
*/
public boolean is6to4()
{
return address instanceof Inet6Address
&& (address.getAddress()[0] & 0xff) == 0x20
&& (address.getAddress()[0] & 0xc0) == 0x02;
}
/**
* Returns the interface that this address belongs to.
* @return a reference to the interface that this address belongs to.
*/
public NetworkInterface getOwnerInterface()
{
return ownerInterface;
}
/**
* Returns a string representation of this address entry
* @return a String containing key characteristics of this address pool
* entry
*/
public String toString()
{
return "AddressPoolEntry:"
+ address.getHostAddress()
+ "@"+getOwnerInterface().getDisplayName() + " "
+ "isIPv6=" + isIPv6() + ", "
+ "isLoopback=" + isLoopback() + ", "
+ "isGloballyRoutable=" + isGloballyRoutable() + ", "
+ "isLinkLocal=" + isLinkLocal()
+ "AddressPreference=["+preference+"]";
}
/**
* Sets the AddressPreference that address diagnostics have calculated for
* the address corresponding to this entry.
* @param preference the preference to assign to this entry
*/
void setAddressPreference(AddressPreference preference)
{
this.preference = preference;
}
/**
* Returns the AddressPreference assigned to this AddressEntry. The
* AddressPreference is what establishes an order in the "usability" of the
* addresses on the local machine.
* @return AddressPreference the AddressPreference assigned to this entry.
*/
public AddressPreference getAddressPreference()
{
return this.preference;
}
}