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 gnu
.java
.lang
.CPStringBuilder
;
43 import java
.util
.Arrays
;
44 import java
.io
.ObjectInputStream
;
45 import java
.io
.ObjectOutputStream
;
46 import java
.io
.IOException
;
49 * Written using on-line Java Platform 1.4 API Specification and
50 * RFC 1884 (http://www.ietf.org/rfc/rfc1884.txt)
52 * @author Michael Koch
53 * @status Updated to 1.5. Serialization compatibility is tested.
55 public final class Inet6Address
extends InetAddress
57 static final long serialVersionUID
= 6880410070516793377L;
60 * Needed for serialization
65 * The scope ID, if any.
72 * The scope ID, if any.
76 private boolean scope_id_set
;
79 * Whether ifname is set or not.
83 private boolean scope_ifname_set
;
86 * Name of the network interface, used only by the serialization methods
90 private String ifname
;
93 * Scope network interface, or <code>null</code>.
95 private transient NetworkInterface nif
;
98 * The address family of these addresses (used for serialization).
100 private static final int AF_INET6
= 10;
103 * Create an Inet6Address object
105 * @param addr The IP address
106 * @param host The hostname
108 Inet6Address(byte[] addr
, String host
)
110 super(addr
, host
, AF_INET6
);
111 // Super constructor clones the addr. Get a reference to the clone.
112 this.ipaddress
= this.addr
;
114 scope_ifname_set
= scope_id_set
= false;
120 * Utility routine to check if the InetAddress is an IP multicast address
124 public boolean isMulticastAddress()
126 return ipaddress
[0] == (byte) 0xFF;
130 * Utility routine to check if the InetAddress in a wildcard address
134 public boolean isAnyLocalAddress()
136 byte[] anylocal
= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
138 return Arrays
.equals(ipaddress
, anylocal
);
142 * Utility routine to check if the InetAddress is a loopback address
146 public boolean isLoopbackAddress()
148 byte[] loopback
= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
150 return Arrays
.equals(ipaddress
, loopback
);
154 * Utility routine to check if the InetAddress is an link local address
158 public boolean isLinkLocalAddress()
160 return ipaddress
[0] == 0xFA;
164 * Utility routine to check if the InetAddress is a site local address
168 public boolean isSiteLocalAddress()
170 return ipaddress
[0] == 0xFB;
174 * Utility routine to check if the multicast address has global scope
178 public boolean isMCGlobal()
180 if (! isMulticastAddress())
183 return (ipaddress
[1] & 0x0F) == 0xE;
187 * Utility routine to check if the multicast address has node scope
191 public boolean isMCNodeLocal()
193 if (! isMulticastAddress())
196 return (ipaddress
[1] & 0x0F) == 0x1;
200 * Utility routine to check if the multicast address has link scope
204 public boolean isMCLinkLocal()
206 if (! isMulticastAddress())
209 return (ipaddress
[1] & 0x0F) == 0x2;
213 * Utility routine to check if the multicast address has site scope
217 public boolean isMCSiteLocal()
219 if (! isMulticastAddress())
222 return (ipaddress
[1] & 0x0F) == 0x5;
226 * Utility routine to check if the multicast address has organization scope
230 public boolean isMCOrgLocal()
232 if (! isMulticastAddress())
235 return (ipaddress
[1] & 0x0F) == 0x8;
239 * Returns the raw IP address of this InetAddress object. The result is in
240 * network byte order: the highest order byte of the address is i
243 public byte[] getAddress()
245 return (byte[]) ipaddress
.clone();
249 * Creates a scoped Inet6Address where the scope has an integer id.
251 * @throws UnkownHostException if the address is an invalid number of bytes.
254 public static Inet6Address
getByAddress(String host
, byte[] addr
,
256 throws UnknownHostException
258 if( addr
.length
!= 16 )
259 throw new UnknownHostException("Illegal address length: " + addr
.length
261 Inet6Address ip
= new Inet6Address( addr
, host
);
262 ip
.scope_id
= scopeId
;
263 ip
.scope_id_set
= true;
268 * Creates a scoped Inet6Address where the scope is a given
271 * @throws UnkownHostException if the address is an invalid number of bytes.
274 public static Inet6Address
getByAddress(String host
, byte[] addr
,
275 NetworkInterface nif
)
276 throws UnknownHostException
278 if( addr
.length
!= 16 )
279 throw new UnknownHostException("Illegal address length: " + addr
.length
281 Inet6Address ip
= new Inet6Address( addr
, host
);
288 * Returns the <code>NetworkInterface</code> of the address scope
289 * if it is a scoped address and the scope is given in the form of a
291 * (I.e. the address was created using the
292 * getByAddress(String, byte[], NetworkInterface) method)
293 * Otherwise this method returns <code>null</code>.
296 public NetworkInterface
getScopedInterface()
302 * Returns the scope ID of the address scope if it is a scoped adress using
303 * an integer to identify the scope.
305 * Otherwise this method returns 0.
308 public int getScopeId()
310 // check scope_id_set because some JDK-serialized objects seem to have
311 // scope_id set to a nonzero value even when scope_id_set == false
318 * Returns the IP address string in textual presentation
320 public String
getHostAddress()
322 CPStringBuilder sbuf
= new CPStringBuilder(40);
324 for (int i
= 0; i
< 16; i
+= 2)
326 int x
= ((ipaddress
[i
] & 0xFF) << 8) | (ipaddress
[i
+ 1] & 0xFF);
331 sbuf
.append(Integer
.toHexString(x
));
334 sbuf
.append( "%" + nif
.getName() );
335 else if( scope_id_set
)
336 sbuf
.append( "%" + scope_id
);
338 return sbuf
.toString();
342 * Returns a hashcode for this IP address
343 * (The hashcode is independent of scope)
345 public int hashCode()
347 return super.hashCode();
351 * Compares this object against the specified object
353 public boolean equals(Object obj
)
355 if (! (obj
instanceof Inet6Address
))
358 Inet6Address ip
= (Inet6Address
)obj
;
359 if (ipaddress
.length
!= ip
.ipaddress
.length
)
362 for (int i
= 0; i
< ip
.ipaddress
.length
; i
++)
363 if (ipaddress
[i
] != ip
.ipaddress
[i
])
366 if( ip
.nif
!= null && nif
!= null )
367 return nif
.equals( ip
.nif
);
370 if( ip
.scope_id_set
!= scope_id_set
)
373 return (scope_id
== ip
.scope_id
);
378 * Utility routine to check if the InetAddress is an
379 * IPv4 compatible IPv6 address
383 public boolean isIPv4CompatibleAddress()
385 if (ipaddress
[0] != 0x00 || ipaddress
[1] != 0x00 || ipaddress
[2] != 0x00
386 || ipaddress
[3] != 0x00 || ipaddress
[4] != 0x00
387 || ipaddress
[5] != 0x00 || ipaddress
[6] != 0x00
388 || ipaddress
[7] != 0x00 || ipaddress
[8] != 0x00
389 || ipaddress
[9] != 0x00 || ipaddress
[10] != 0x00
390 || ipaddress
[11] != 0x00)
397 * Required for 1.5-compatible serialization.
400 private void readObject(ObjectInputStream s
)
401 throws IOException
, ClassNotFoundException
403 s
.defaultReadObject();
406 if( scope_ifname_set
)
407 nif
= NetworkInterface
.getByName( ifname
);
409 catch( SocketException se
)
411 // FIXME: Ignore this? or throw an IOException?
416 * Required for 1.5-compatible serialization.
419 private void writeObject(ObjectOutputStream s
)
424 ifname
= nif
.getName();
425 scope_ifname_set
= true;
427 s
.defaultWriteObject();