1 /* Inet6Address.java --
2 Copyright (C) 2002, 2003, 2004, 2006 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 * The address family of these addresses (used for serialization).
98 private static final int AF_INET6 = 10;
101 * Create an Inet6Address object
103 * @param addr The IP address
104 * @param host The hostname
106 Inet6Address(byte[] addr, String host)
108 super(addr, host, AF_INET6);
109 // Super constructor clones the addr. Get a reference to the clone.
110 this.ipaddress = this.addr;
112 scope_ifname_set = scope_id_set = false;
118 * Utility routine to check if the InetAddress is an IP multicast address
122 public boolean isMulticastAddress()
124 return ipaddress[0] == (byte) 0xFF;
128 * Utility routine to check if the InetAddress in a wildcard address
132 public boolean isAnyLocalAddress()
134 byte[] anylocal = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
136 return Arrays.equals(ipaddress, anylocal);
140 * Utility routine to check if the InetAddress is a loopback address
144 public boolean isLoopbackAddress()
146 byte[] loopback = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
148 return Arrays.equals(ipaddress, loopback);
152 * Utility routine to check if the InetAddress is an link local address
156 public boolean isLinkLocalAddress()
158 return ipaddress[0] == 0xFA;
162 * Utility routine to check if the InetAddress is a site local address
166 public boolean isSiteLocalAddress()
168 return ipaddress[0] == 0xFB;
172 * Utility routine to check if the multicast address has global scope
176 public boolean isMCGlobal()
178 if (! isMulticastAddress())
181 return (ipaddress[1] & 0x0F) == 0xE;
185 * Utility routine to check if the multicast address has node scope
189 public boolean isMCNodeLocal()
191 if (! isMulticastAddress())
194 return (ipaddress[1] & 0x0F) == 0x1;
198 * Utility routine to check if the multicast address has link scope
202 public boolean isMCLinkLocal()
204 if (! isMulticastAddress())
207 return (ipaddress[1] & 0x0F) == 0x2;
211 * Utility routine to check if the multicast address has site scope
215 public boolean isMCSiteLocal()
217 if (! isMulticastAddress())
220 return (ipaddress[1] & 0x0F) == 0x5;
224 * Utility routine to check if the multicast address has organization scope
228 public boolean isMCOrgLocal()
230 if (! isMulticastAddress())
233 return (ipaddress[1] & 0x0F) == 0x8;
237 * Returns the raw IP address of this InetAddress object. The result is in
238 * network byte order: the highest order byte of the address is i
241 public byte[] getAddress()
243 return (byte[]) ipaddress.clone();
247 * Creates a scoped Inet6Address where the scope has an integer id.
249 * @throws UnkownHostException if the address is an invalid number of bytes.
252 public static Inet6Address getByAddress(String host, byte[] addr,
254 throws UnknownHostException
256 if( addr.length != 16 )
257 throw new UnknownHostException("Illegal address length: " + addr.length
259 Inet6Address ip = new Inet6Address( addr, host );
260 ip.scope_id = scopeId;
261 ip.scope_id_set = true;
266 * Creates a scoped Inet6Address where the scope is a given
269 * @throws UnkownHostException if the address is an invalid number of bytes.
272 public static Inet6Address getByAddress(String host, byte[] addr,
273 NetworkInterface nif)
274 throws UnknownHostException
276 if( addr.length != 16 )
277 throw new UnknownHostException("Illegal address length: " + addr.length
279 Inet6Address ip = new Inet6Address( addr, host );
286 * Returns the <code>NetworkInterface</code> of the address scope
287 * if it is a scoped address and the scope is given in the form of a
289 * (I.e. the address was created using the
290 * getByAddress(String, byte[], NetworkInterface) method)
291 * Otherwise this method returns <code>null</code>.
294 public NetworkInterface getScopedInterface()
300 * Returns the scope ID of the address scope if it is a scoped adress using
301 * an integer to identify the scope.
303 * Otherwise this method returns 0.
306 public int getScopeId()
308 // check scope_id_set because some JDK-serialized objects seem to have
309 // scope_id set to a nonzero value even when scope_id_set == false
316 * Returns the IP address string in textual presentation
318 public String getHostAddress()
320 StringBuffer sbuf = new StringBuffer(40);
322 for (int i = 0; i < 16; i += 2)
324 int x = ((ipaddress[i] & 0xFF) << 8) | (ipaddress[i + 1] & 0xFF);
329 sbuf.append(Integer.toHexString(x));
332 sbuf.append( "%" + nif.getName() );
333 else if( scope_id_set )
334 sbuf.append( "%" + scope_id );
336 return sbuf.toString();
340 * Returns a hashcode for this IP address
341 * (The hashcode is independent of scope)
343 public int hashCode()
345 return super.hashCode();
349 * Compares this object against the specified object
351 public boolean equals(Object obj)
353 if (! (obj instanceof Inet6Address))
356 Inet6Address ip = (Inet6Address)obj;
357 if (ipaddress.length != ip.ipaddress.length)
360 for (int i = 0; i < ip.ipaddress.length; i++)
361 if (ipaddress[i] != ip.ipaddress[i])
364 if( ip.nif != null && nif != null )
365 return nif.equals( ip.nif );
368 if( ip.scope_id_set != scope_id_set )
371 return (scope_id == ip.scope_id);
376 * Utility routine to check if the InetAddress is an
377 * IPv4 compatible IPv6 address
381 public boolean isIPv4CompatibleAddress()
383 if (ipaddress[0] != 0x00 || ipaddress[1] != 0x00 || ipaddress[2] != 0x00
384 || ipaddress[3] != 0x00 || ipaddress[4] != 0x00
385 || ipaddress[5] != 0x00 || ipaddress[6] != 0x00
386 || ipaddress[7] != 0x00 || ipaddress[8] != 0x00
387 || ipaddress[9] != 0x00 || ipaddress[10] != 0x00
388 || ipaddress[11] != 0x00)
395 * Required for 1.5-compatible serialization.
398 private void readObject(ObjectInputStream s)
399 throws IOException, ClassNotFoundException
401 s.defaultReadObject();
404 if( scope_ifname_set )
405 nif = NetworkInterface.getByName( ifname );
407 catch( SocketException se )
409 // FIXME: Ignore this? or throw an IOException?
414 * Required for 1.5-compatible serialization.
417 private void writeObject(ObjectOutputStream s)
422 ifname = nif.getName();
423 scope_ifname_set = true;
425 s.defaultWriteObject();