/* * Conditions Of Use * * This software was developed by employees of the National Institute of * Standards and Technology (NIST), an agency of the Federal Government. * Pursuant to title 15 Untied States Code Section 105, works of NIST * employees are not subject to copyright protection in the United States * and are considered to be in the public domain. As a result, a formal * license is not needed to use the software. * * This software is provided by NIST as a service and is expressly * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT * AND DATA ACCURACY. NIST does not warrant or make any representations * regarding the use of the software or the results thereof, including but * not limited to the correctness, accuracy, reliability or usefulness of * the software. * * Permission to use this software is contingent upon your acceptance * of the terms of this agreement * * . * */ /*************************************************************************** * Product of NIST/ITL Advanced Networking Technologies Division(ANTD). * **************************************************************************/ package gov.nist.core; import java.net.*; /* * IPv6 Support added by Emil Ivov (emil_ivov@yahoo.com)
* Network Research Team (http://www-r2.u-strasbg.fr))
* Louis Pasteur University - Strasbourg - France
* * Frank Feif reported a bug. * * */ /** * Stores hostname. * @version 1.2 * * @author M. Ranganathan * @author Emil Ivov IPV6 Support.
* * * * Marc Bednarek (Bugfixes).
* */ public class Host extends GenericObject { /** * Determines whether or not we should tolerate and strip address scope * zones from IPv6 addresses. Address scope zones are sometimes returned * at the end of IPv6 addresses generated by InetAddress.getHostAddress(). * They are however not part of the SIP semantics so basically this method * determines whether or not the parser should be stripping them (as * opposed simply being blunt and throwing an exception). */ private boolean stripAddressScopeZones = false; private static final long serialVersionUID = -7233564517978323344L; protected static final int HOSTNAME = 1; protected static final int IPV4ADDRESS = 2; protected static final int IPV6ADDRESS = 3; /** hostName field */ protected String hostname; /** address field */ protected int addressType; private InetAddress inetAddress; /** default constructor */ public Host() { addressType = HOSTNAME; stripAddressScopeZones = Boolean.getBoolean("gov.nist.core.STRIP_ADDR_SCOPES"); } /** Constructor given host name or IP address. */ public Host(String hostName) throws IllegalArgumentException { if (hostName == null) throw new IllegalArgumentException("null host name"); stripAddressScopeZones = Boolean.getBoolean("gov.nist.core.STRIP_ADDR_SCOPES"); setHost(hostName, IPV4ADDRESS); } /** constructor * @param name String to set * @param addrType int to set */ public Host(String name, int addrType) { stripAddressScopeZones = Boolean.getBoolean("gov.nist.core.STRIP_ADDR_SCOPES"); setHost(name, addrType); } /** * Return the host name in encoded form. * @return String */ public String encode() { return encode(new StringBuffer()).toString(); } public StringBuffer encode(StringBuffer buffer) { if (addressType == IPV6ADDRESS && !isIPv6Reference(hostname)) { buffer.append('[').append(hostname).append(']'); } else { buffer.append(hostname); } return buffer; } /** * Compare for equality of hosts. * Host names are compared by textual equality. No dns lookup * is performed. * @param obj Object to set * @return boolean */ public boolean equals(Object obj) { if ( obj == null ) return false; if (!this.getClass().equals(obj.getClass())) { return false; } Host otherHost = (Host) obj; return otherHost.hostname.equals(hostname); } /** get the HostName field * @return String */ public String getHostname() { return hostname; } /** get the Address field * @return String */ public String getAddress() { return hostname; } /** * Convenience function to get the raw IP destination address * of a SIP message as a String. * @return String */ public String getIpAddress() { String rawIpAddress = null; if (hostname == null) return null; if (addressType == HOSTNAME) { try { if (inetAddress == null) inetAddress = InetAddress.getByName(hostname); rawIpAddress = inetAddress.getHostAddress(); } catch (UnknownHostException ex) { dbgPrint("Could not resolve hostname " + ex); } } else { rawIpAddress = hostname; } return rawIpAddress; } /** * Set the hostname member. * @param h String to set */ public void setHostname(String h) { setHost(h, HOSTNAME); } /** Set the IP Address. *@param address is the address string to set. */ public void setHostAddress(String address) { setHost(address, IPV4ADDRESS); } /** * Sets the host address or name of this object. * * @param host that host address/name value * @param type determines whether host is an address or a host name */ private void setHost(String host, int type){ //set inetAddress to null so that it would be reinited //upon next call to getInetAddress() inetAddress = null; if (isIPv6Address(host)) addressType = IPV6ADDRESS; else addressType = type; // Null check bug fix sent in by jpaulo@ipb.pt if (host != null){ hostname = host.trim(); //if this is an FQDN, make it lowercase to simplify processing if(addressType == HOSTNAME) hostname = hostname.toLowerCase(); //remove address scope zones if this is an IPv6 address as they //are not allowed by the RFC int zoneStart = -1; if(addressType == IPV6ADDRESS && stripAddressScopeZones && (zoneStart = hostname.indexOf('%'))!= -1){ hostname = hostname.substring(0, zoneStart); } } } /** * Set the address member * @param address address String to set */ public void setAddress(String address) { this.setHostAddress(address); } /** Return true if the address is a DNS host name * (and not an IPV4 address) *@return true if the hostname is a DNS name */ public boolean isHostname() { return addressType == HOSTNAME; } /** Return true if the address is a DNS host name * (and not an IPV4 address) *@return true if the hostname is host address. */ public boolean isIPAddress() { return addressType != HOSTNAME; } /** Get the inet address from this host. * Caches the inet address returned from dns lookup to avoid * lookup delays. * *@throws UnkownHostexception when the host name cannot be resolved. */ public InetAddress getInetAddress() throws java.net.UnknownHostException { if (hostname == null) return null; if (inetAddress != null) return inetAddress; inetAddress = InetAddress.getByName(hostname); return inetAddress; } //----- IPv6 /** * Verifies whether the address could * be an IPv6 address */ private boolean isIPv6Address(String address) { return (address != null && address.indexOf(':') != -1); } /** * Verifies whether the ipv6reference, i.e. whether it enclosed in * square brackets */ public static boolean isIPv6Reference(String address) { return address.charAt(0) == '[' && address.charAt(address.length() - 1) == ']'; } @Override public int hashCode() { return this.getHostname().hashCode(); } }