1 /* Inet6Address.java --
2 Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java.util.Arrays;
42 import java.io.ObjectInputStream;
43 import java.io.ObjectOutputStream;
44 import java.io.IOException;
47 * Written using on-line Java Platform 1.4 API Specification and
48 * RFC 1884 (http://www.ietf.org/rfc/rfc1884.txt)
50 * @author Michael Koch
51 * @status Updated to 1.5. Serialization compatibility is tested.
53 public final class Inet6Address extends InetAddress
55 static final long serialVersionUID = 6880410070516793377L;
58 * Needed for serialization
63 * The scope ID, if any.
70 * The scope ID, if any.
74 private boolean scope_id_set;
77 * Whether ifname is set or not.
81 private boolean scope_ifname_set;
84 * Name of the network interface, used only by the serialization methods
88 private String ifname;
91 * Scope network interface, or <code>null</code>.
93 private transient NetworkInterface nif;
96 * Create an Inet6Address object
98 * @param addr The IP address
99 * @param host The hostname
101 Inet6Address(byte[] addr, String host)
104 // Super constructor clones the addr. Get a reference to the clone.
105 this.ipaddress = this.addr;
107 scope_ifname_set = scope_id_set = false;
113 * Utility routine to check if the InetAddress is an IP multicast address
117 public boolean isMulticastAddress()
119 return ipaddress[0] == 0xFF;
123 * Utility routine to check if the InetAddress in a wildcard address
127 public boolean isAnyLocalAddress()
129 byte[] anylocal = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
131 return Arrays.equals(ipaddress, anylocal);
135 * Utility routine to check if the InetAddress is a loopback address
139 public boolean isLoopbackAddress()
141 byte[] loopback = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
143 return Arrays.equals(ipaddress, loopback);
147 * Utility routine to check if the InetAddress is an link local address
151 public boolean isLinkLocalAddress()
153 return ipaddress[0] == 0xFA;
157 * Utility routine to check if the InetAddress is a site local address
161 public boolean isSiteLocalAddress()
163 return ipaddress[0] == 0xFB;
167 * Utility routine to check if the multicast address has global scope
171 public boolean isMCGlobal()
173 if (! isMulticastAddress())
176 return (ipaddress[1] & 0x0F) == 0xE;
180 * Utility routine to check if the multicast address has node scope
184 public boolean isMCNodeLocal()
186 if (! isMulticastAddress())
189 return (ipaddress[1] & 0x0F) == 0x1;
193 * Utility routine to check if the multicast address has link scope
197 public boolean isMCLinkLocal()
199 if (! isMulticastAddress())
202 return (ipaddress[1] & 0x0F) == 0x2;
206 * Utility routine to check if the multicast address has site scope
210 public boolean isMCSiteLocal()
212 if (! isMulticastAddress())
215 return (ipaddress[1] & 0x0F) == 0x5;
219 * Utility routine to check if the multicast address has organization scope
223 public boolean isMCOrgLocal()
225 if (! isMulticastAddress())
228 return (ipaddress[1] & 0x0F) == 0x8;
232 * Returns the raw IP address of this InetAddress object. The result is in
233 * network byte order: the highest order byte of the address is i
236 public byte[] getAddress()
238 return (byte[]) ipaddress.clone();
242 * Creates a scoped Inet6Address where the scope has an integer id.
244 * @throws UnkownHostException if the address is an invalid number of bytes.
247 public static Inet6Address getByAddress(String host, byte[] addr,
249 throws UnknownHostException
251 if( addr.length != 16 )
252 throw new UnknownHostException("Illegal address length: " + addr.length
254 Inet6Address ip = new Inet6Address( addr, host );
255 ip.scope_id = scopeId;
256 ip.scope_id_set = true;
261 * Creates a scoped Inet6Address where the scope is a given
264 * @throws UnkownHostException if the address is an invalid number of bytes.
267 public static Inet6Address getByAddress(String host, byte[] addr,
268 NetworkInterface nif)
269 throws UnknownHostException
271 if( addr.length != 16 )
272 throw new UnknownHostException("Illegal address length: " + addr.length
274 Inet6Address ip = new Inet6Address( addr, host );
281 * Returns the <code>NetworkInterface</code> of the address scope
282 * if it is a scoped address and the scope is given in the form of a
284 * (I.e. the address was created using the
285 * getByAddress(String, byte[], NetworkInterface) method)
286 * Otherwise this method returns <code>null</code>.
289 public NetworkInterface getScopedInterface()
295 * Returns the scope ID of the address scope if it is a scoped adress using
296 * an integer to identify the scope.
298 * Otherwise this method returns 0.
301 public int getScopeId()
303 // check scope_id_set because some JDK-serialized objects seem to have
304 // scope_id set to a nonzero value even when scope_id_set == false
311 * Returns the IP address string in textual presentation
313 public String getHostAddress()
315 StringBuffer sbuf = new StringBuffer(40);
317 for (int i = 0; i < 16; i += 2)
319 int x = ((ipaddress[i] & 0xFF) << 8) | (ipaddress[i + 1] & 0xFF);
324 sbuf.append(Integer.toHexString(x));
327 sbuf.append( "%" + nif.getName() );
328 else if( scope_id_set )
329 sbuf.append( "%" + scope_id );
331 return sbuf.toString();
335 * Returns a hashcode for this IP address
336 * (The hashcode is independent of scope)
338 public int hashCode()
340 return super.hashCode();
344 * Compares this object against the specified object
346 public boolean equals(Object obj)
348 if (! (obj instanceof Inet6Address))
351 Inet6Address ip = (Inet6Address)obj;
352 if (ipaddress.length != ip.ipaddress.length)
355 for (int i = 0; i < ip.ipaddress.length; i++)
356 if (ipaddress[i] != ip.ipaddress[i])
359 if( ip.nif != null && nif != null )
360 return nif.equals( ip.nif );
363 if( ip.scope_id_set != scope_id_set )
366 return (scope_id == ip.scope_id);
371 * Utility routine to check if the InetAddress is an
372 * IPv4 compatible IPv6 address
376 public boolean isIPv4CompatibleAddress()
378 if (ipaddress[0] != 0x00 || ipaddress[1] != 0x00 || ipaddress[2] != 0x00
379 || ipaddress[3] != 0x00 || ipaddress[4] != 0x00
380 || ipaddress[5] != 0x00 || ipaddress[6] != 0x00
381 || ipaddress[7] != 0x00 || ipaddress[8] != 0x00
382 || ipaddress[9] != 0x00 || ipaddress[10] != 0x00
383 || ipaddress[11] != 0x00)
390 * Required for 1.5-compatible serialization.
393 private void readObject(ObjectInputStream s)
394 throws IOException, ClassNotFoundException
396 s.defaultReadObject();
399 if( scope_ifname_set )
400 nif = NetworkInterface.getByName( ifname );
402 catch( SocketException se )
404 // FIXME: Ignore this? or throw an IOException?
409 * Required for 1.5-compatible serialization.
412 private void writeObject(ObjectOutputStream s)
417 ifname = nif.getName();
418 scope_ifname_set = true;
420 s.defaultWriteObject();