• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Conditions Of Use
3 *
4 * This software was developed by employees of the National Institute of
5 * Standards and Technology (NIST), an agency of the Federal Government.
6 * Pursuant to title 15 Untied States Code Section 105, works of NIST
7 * employees are not subject to copyright protection in the United States
8 * and are considered to be in the public domain.  As a result, a formal
9 * license is not needed to use the software.
10 *
11 * This software is provided by NIST as a service and is expressly
12 * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
13 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
14 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
15 * AND DATA ACCURACY.  NIST does not warrant or make any representations
16 * regarding the use of the software or the results thereof, including but
17 * not limited to the correctness, accuracy, reliability or usefulness of
18 * the software.
19 *
20 * Permission to use this software is contingent upon your acceptance
21 * of the terms of this agreement
22 *
23 * .
24 *
25 */
26 /***************************************************************************
27  * Product of NIST/ITL Advanced Networking Technologies Division(ANTD).   *
28  **************************************************************************/
29 package gov.nist.core;
30 
31 import java.net.*;
32 
33 /*
34  * IPv6 Support added by Emil Ivov (emil_ivov@yahoo.com)<br/>
35  * Network Research Team (http://www-r2.u-strasbg.fr))<br/>
36  * Louis Pasteur University - Strasbourg - France<br/>
37  *
38  * Frank Feif reported a bug.
39  *
40  *
41  */
42 /**
43  * Stores hostname.
44  * @version 1.2
45  *
46  * @author M. Ranganathan
47  * @author Emil Ivov <emil_ivov@yahoo.com> IPV6 Support. <br/>
48  *
49  *
50  *
51 
52  * Marc Bednarek <bednarek@nist.gov> (Bugfixes).<br/>
53  *
54  */
55 public class Host extends GenericObject {
56 
57     /**
58      * Determines whether or not we should tolerate and strip address scope
59      * zones from IPv6 addresses. Address scope zones are sometimes returned
60      * at the end of IPv6 addresses generated by InetAddress.getHostAddress().
61      * They are however not part of the SIP semantics so basically this method
62      * determines whether or not the parser should be stripping them (as
63      * opposed simply being blunt and throwing an exception).
64      */
65     private boolean stripAddressScopeZones = false;
66 
67     private static final long serialVersionUID = -7233564517978323344L;
68     protected static final int HOSTNAME = 1;
69     protected static final int IPV4ADDRESS = 2;
70     protected static final int IPV6ADDRESS = 3;
71 
72     /** hostName field
73      */
74     protected String hostname;
75 
76     /** address field
77      */
78 
79     protected int addressType;
80 
81     private InetAddress inetAddress;
82 
83     /** default constructor
84      */
Host()85     public Host() {
86         addressType = HOSTNAME;
87 
88         stripAddressScopeZones
89             = Boolean.getBoolean("gov.nist.core.STRIP_ADDR_SCOPES");
90     }
91 
92     /** Constructor given host name or IP address.
93      */
Host(String hostName)94     public Host(String hostName) throws IllegalArgumentException {
95         if (hostName == null)
96             throw new IllegalArgumentException("null host name");
97 
98         stripAddressScopeZones
99             = Boolean.getBoolean("gov.nist.core.STRIP_ADDR_SCOPES");
100 
101         setHost(hostName, IPV4ADDRESS);
102     }
103 
104     /** constructor
105      * @param name String to set
106      * @param addrType int to set
107      */
Host(String name, int addrType)108     public Host(String name, int addrType) {
109         stripAddressScopeZones
110             = Boolean.getBoolean("gov.nist.core.STRIP_ADDR_SCOPES");
111 
112         setHost(name, addrType);
113     }
114 
115     /**
116      * Return the host name in encoded form.
117      * @return String
118      */
encode()119     public String encode() {
120         return encode(new StringBuffer()).toString();
121     }
122 
encode(StringBuffer buffer)123     public StringBuffer encode(StringBuffer buffer) {
124         if (addressType == IPV6ADDRESS && !isIPv6Reference(hostname)) {
125             buffer.append('[').append(hostname).append(']');
126         } else {
127             buffer.append(hostname);
128         }
129         return buffer;
130     }
131 
132     /**
133      * Compare for equality of hosts.
134      * Host names are compared by textual equality. No dns lookup
135      * is performed.
136      * @param obj Object to set
137      * @return boolean
138      */
equals(Object obj)139     public boolean equals(Object obj) {
140         if ( obj == null ) return false;
141         if (!this.getClass().equals(obj.getClass())) {
142             return false;
143         }
144         Host otherHost = (Host) obj;
145         return otherHost.hostname.equals(hostname);
146 
147     }
148 
149     /** get the HostName field
150      * @return String
151      */
getHostname()152     public String getHostname() {
153         return hostname;
154     }
155 
156     /** get the Address field
157      * @return String
158      */
getAddress()159     public String getAddress() {
160         return hostname;
161     }
162 
163     /**
164      * Convenience function to get the raw IP destination address
165      * of a SIP message as a String.
166      * @return String
167      */
getIpAddress()168     public String getIpAddress() {
169         String rawIpAddress = null;
170         if (hostname == null)
171             return null;
172         if (addressType == HOSTNAME) {
173             try {
174                 if (inetAddress == null)
175                     inetAddress = InetAddress.getByName(hostname);
176                 rawIpAddress = inetAddress.getHostAddress();
177             } catch (UnknownHostException ex) {
178                 dbgPrint("Could not resolve hostname " + ex);
179             }
180         } else {
181             rawIpAddress = hostname;
182         }
183         return rawIpAddress;
184     }
185 
186     /**
187      * Set the hostname member.
188      * @param h String to set
189      */
setHostname(String h)190     public void setHostname(String h) {
191         setHost(h, HOSTNAME);
192     }
193 
194     /** Set the IP Address.
195      *@param address is the address string to set.
196      */
setHostAddress(String address)197     public void setHostAddress(String address) {
198         setHost(address, IPV4ADDRESS);
199     }
200 
201     /**
202      * Sets the host address or name of this object.
203      *
204      * @param host that host address/name value
205      * @param type determines whether host is an address or a host name
206      */
setHost(String host, int type)207     private void setHost(String host, int type){
208         //set inetAddress to null so that it would be reinited
209         //upon next call to getInetAddress()
210         inetAddress = null;
211 
212         if (isIPv6Address(host))
213             addressType = IPV6ADDRESS;
214         else
215             addressType = type;
216 
217         // Null check bug fix sent in by jpaulo@ipb.pt
218         if (host != null){
219             hostname = host.trim();
220 
221             //if this is an FQDN, make it lowercase to simplify processing
222             if(addressType == HOSTNAME)
223                 hostname = hostname.toLowerCase();
224 
225             //remove address scope zones if this is an IPv6 address as they
226             //are not allowed by the RFC
227             int zoneStart = -1;
228             if(addressType == IPV6ADDRESS
229                 && stripAddressScopeZones
230                 && (zoneStart = hostname.indexOf('%'))!= -1){
231 
232                 hostname = hostname.substring(0, zoneStart);
233             }
234         }
235     }
236 
237     /**
238      * Set the address member
239      * @param address address String to set
240      */
setAddress(String address)241     public void setAddress(String address) {
242         this.setHostAddress(address);
243     }
244 
245     /** Return true if the address is a DNS host name
246      *  (and not an IPV4 address)
247      *@return true if the hostname is a DNS name
248      */
isHostname()249     public boolean isHostname() {
250         return addressType == HOSTNAME;
251     }
252 
253     /** Return true if the address is a DNS host name
254      *  (and not an IPV4 address)
255      *@return true if the hostname is host address.
256      */
isIPAddress()257     public boolean isIPAddress() {
258         return addressType != HOSTNAME;
259     }
260 
261     /** Get the inet address from this host.
262      * Caches the inet address returned from dns lookup to avoid
263      * lookup delays.
264      *
265      *@throws UnkownHostexception when the host name cannot be resolved.
266      */
getInetAddress()267     public InetAddress getInetAddress() throws java.net.UnknownHostException {
268         if (hostname == null)
269             return null;
270         if (inetAddress != null)
271             return inetAddress;
272         inetAddress = InetAddress.getByName(hostname);
273         return inetAddress;
274 
275     }
276 
277     //----- IPv6
278     /**
279      * Verifies whether the <code>address</code> could
280      * be an IPv6 address
281      */
isIPv6Address(String address)282     private boolean isIPv6Address(String address) {
283         return (address != null && address.indexOf(':') != -1);
284     }
285 
286     /**
287      * Verifies whether the ipv6reference, i.e. whether it enclosed in
288      * square brackets
289      */
isIPv6Reference(String address)290     public static boolean isIPv6Reference(String address) {
291         return address.charAt(0) == '['
292             && address.charAt(address.length() - 1) == ']';
293     }
294 
295     @Override
hashCode()296     public int hashCode() {
297         return this.getHostname().hashCode();
298 
299     }
300 }
301