KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > net > Inet6Address


1 /*
2  * @(#)Inet6Address.java 1.37 06/04/07
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.net;
9
10 import java.security.AccessController JavaDoc;
11 import java.io.ObjectInputStream JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.ObjectStreamException JavaDoc;
14 import java.io.InvalidObjectException JavaDoc;
15 import sun.security.action.*;
16 import java.util.Enumeration JavaDoc;
17
18 /**
19  * This class represents an Internet Protocol version 6 (IPv6) address.
20  * Defined by <a HREF="http://www.ietf.org/rfc/rfc2373.txt">
21  * <i>RFC&nbsp;2373: IP Version 6 Addressing Architecture</i></a>.
22  *
23  * <h4> <A NAME="format">Textual representation of IP addresses</a> </h4>
24  *
25  * Textual representation of IPv6 address used as input to methods
26  * takes one of the following forms:
27  *
28  * <ol>
29  * <li><p> <A NAME="lform">The preferred form</a> is x:x:x:x:x:x:x:x,
30  * where the 'x's are
31  * the hexadecimal values of the eight 16-bit pieces of the
32  * address. This is the full form. For example,
33  *
34  * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
35  * <tr><td><tt>1080:0:0:0:8:800:200C:417A</tt><td></tr>
36  * </table></blockquote>
37  *
38  * <p> Note that it is not necessary to write the leading zeros in
39  * an individual field. However, there must be at least one numeral
40  * in every field, except as described below.</li>
41  *
42  * <li><p> Due to some methods of allocating certain styles of IPv6
43  * addresses, it will be common for addresses to contain long
44  * strings of zero bits. In order to make writing addresses
45  * containing zero bits easier, a special syntax is available to
46  * compress the zeros. The use of "::" indicates multiple groups
47  * of 16-bits of zeros. The "::" can only appear once in an address.
48  * The "::" can also be used to compress the leading and/or trailing
49  * zeros in an address. For example,
50  *
51  * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
52  * <tr><td><tt>1080::8:800:200C:417A</tt><td></tr>
53  * </table></blockquote>
54  *
55  * <li><p> An alternative form that is sometimes more convenient
56  * when dealing with a mixed environment of IPv4 and IPv6 nodes is
57  * x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
58  * of the six high-order 16-bit pieces of the address, and the 'd's
59  * are the decimal values of the four low-order 8-bit pieces of the
60  * standard IPv4 representation address, for example,
61  *
62  * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
63  * <tr><td><tt>::FFFF:129.144.52.38</tt><td></tr>
64  * <tr><td><tt>::129.144.52.38</tt><td></tr>
65  * </table></blockquote>
66  *
67  * <p> where "::FFFF:d.d.d.d" and "::d.d.d.d" are, respectively, the
68  * general forms of an IPv4-mapped IPv6 address and an
69  * IPv4-compatible IPv6 address. Note that the IPv4 portion must be
70  * in the "d.d.d.d" form. The following forms are invalid:
71  *
72  * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
73  * <tr><td><tt>::FFFF:d.d.d</tt><td></tr>
74  * <tr><td><tt>::FFFF:d.d</tt><td></tr>
75  * <tr><td><tt>::d.d.d</tt><td></tr>
76  * <tr><td><tt>::d.d</tt><td></tr>
77  * </table></blockquote>
78  *
79  * <p> The following form:
80  *
81  * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
82  * <tr><td><tt>::FFFF:d</tt><td></tr>
83  * </table></blockquote>
84  *
85  * <p> is valid, however it is an unconventional representation of
86  * the IPv4-compatible IPv6 address,
87  *
88  * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
89  * <tr><td><tt>::255.255.0.d</tt><td></tr>
90  * </table></blockquote>
91  *
92  * <p> while "::d" corresponds to the general IPv6 address
93  * "0:0:0:0:0:0:0:d".</li>
94  * </ol>
95  *
96  * <p> For methods that return a textual representation as output
97  * value, the full form is used. Inet6Address will return the full
98  * form because it is unambiguous when used in combination with other
99  * textual data.
100  *
101  * <h4> Special IPv6 address </h4>
102  *
103  * <blockquote>
104  * <table cellspacing=2 summary="Description of IPv4-mapped address"> <tr><th valign=top><i>IPv4-mapped address</i></th>
105  * <td>Of the form::ffff:w.x.y.z, this IPv6 address is used to
106  * represent an IPv4 address. It allows the native program to
107  * use the same address data structure and also the same
108  * socket when communicating with both IPv4 and IPv6 nodes.
109  *
110  * <p>In InetAddress and Inet6Address, it is used for internal
111  * representation; it has no functional role. Java will never
112  * return an IPv4-mapped address. These classes can take an
113  * IPv4-mapped address as input, both in byte array and text
114  * representation. However, it will be converted into an IPv4
115  * address.</td></tr>
116  * </table></blockquote>
117  * <p>
118  * <h4> <A NAME="scoped">Textual representation of IPv6 scoped addresses</a> </h4>
119  * <p>
120  * The textual representation of IPv6 addresses as described above can be extended
121  * to specify IPv6 scoped addresses. This extension to the basic addressing architecture
122  * is described in [draft-ietf-ipngwg-scoping-arch-04.txt].
123  * <p>
124  * Because link-local and site-local addresses are non-global, it is possible that different hosts
125  * may have the same destination address and may be reachable through different interfaces on the
126  * same originating system. In this case, the originating system is said to be connected
127  * to multiple zones of the same scope. In order to disambiguate which is the intended destination
128  * zone, it is possible to append a zone identifier (or <i>scope_id</i>) to an IPv6 address.
129  * <p>
130  * The general format for specifying the <i>scope_id</i> is the following:
131  * <p><blockquote><i>IPv6-address</i>%<i>scope_id</i></blockquote>
132  * <p> The IPv6-address is a literal IPv6 address as described above.
133  * The <i>scope_id</i> refers to an interface on the local system, and it can be specified
134  * in two ways.
135  * <p><ol><li><i>As a numeric identifier.</i> This must be a positive integer that identifies the
136  * particular interface and scope as understood by the system. Usually, the numeric
137  * values can be determined through administration tools on the system. Each interface may
138  * have multiple values, one for each scope. If the scope is unspecified, then the default value
139  * used is zero.</li><p>
140  * <li><i>As a string.</i> This must be the exact string that is returned by
141  * {@link java.net.NetworkInterface#getName()} for the particular interface in question.
142  * When an Inet6Address is created in this way, the numeric scope-id is determined at the time
143  * the object is created by querying the relevant NetworkInterface.</li>
144  * </ol><p>
145  * Note also, that the numeric <i>scope_id</i> can be retrieved from Inet6Address instances returned from the
146  * NetworkInterface class. This can be used to find out the current scope ids configured on the system.
147  * @since 1.4
148  */

149
150 public final
151 class Inet6Address extends InetAddress JavaDoc {
152     final static int INADDRSZ = 16;
153
154     /*
155      * cached scope_id - for link-local address use only.
156      */

157     private transient int cached_scope_id = 0;
158
159     /**
160      * Holds a 128-bit (16 bytes) IPv6 address.
161      *
162      * @serial
163      */

164     byte[] ipaddress;
165
166     /**
167      * scope_id. The scope specified when the object is created. If the object is created
168      * with an interface name, then the scope_id is not determined until the time it is needed.
169      */

170     private int scope_id = 0;
171
172     /**
173      * This will be set to true when the scope_id field contains a valid
174      * integer scope_id.
175      */

176     private boolean scope_id_set = false;
177
178     /**
179      * scoped interface. scope_id is derived from this as the scope_id of the first
180      * address whose scope is the same as this address for the named interface.
181      */

182     private transient NetworkInterface JavaDoc scope_ifname = null;
183
184     /**
185      * set if the object is constructed with a scoped interface instead of a
186      * numeric scope id.
187      */

188     private boolean scope_ifname_set = false;
189
190     private static final long serialVersionUID = 6880410070516793377L;
191
192     /*
193      * Perform initializations.
194      */

195     static {
196         init();
197     }
198
199     Inet6Address() {
200     super();
201     hostName = null;
202     ipaddress = new byte[INADDRSZ];
203     family = IPv6;
204     }
205
206     /* checking of value for scope_id should be done by caller
207      * scope_id must be >= 0, or -1 to indicate not being set
208      */

209     Inet6Address(String JavaDoc hostName, byte addr[], int scope_id) {
210     this.hostName = hostName;
211     if (addr.length == INADDRSZ) { // normal IPv6 address
212
family = IPv6;
213         ipaddress = (byte[])addr.clone();
214     }
215     if (scope_id >= 0) {
216         this.scope_id = scope_id;
217         scope_id_set = true;
218     }
219     }
220
221     Inet6Address(String JavaDoc hostName, byte addr[]) {
222     try {
223         initif (hostName, addr, null);
224     } catch (UnknownHostException JavaDoc e) {} /* cant happen if ifname is null */
225     }
226
227     Inet6Address (String JavaDoc hostName, byte addr[], NetworkInterface JavaDoc nif) throws UnknownHostException JavaDoc {
228     initif (hostName, addr, nif);
229     }
230
231     Inet6Address (String JavaDoc hostName, byte addr[], String JavaDoc ifname) throws UnknownHostException JavaDoc {
232     initstr (hostName, addr, ifname);
233     }
234
235     /**
236      * Create an Inet6Address in the exact manner of {@link InetAddress#getByAddress(String,byte[])}
237      * except that the IPv6 scope_id is set to the value corresponding to the given interface
238      * for the address type specified in <code>addr</code>.
239      * The call will fail with an UnknownHostException if the given interface does not have a numeric
240      * scope_id assigned for the given address type (eg. link-local or site-local).
241      * See <a HREF="Inet6Address.html#scoped">here</a> for a description of IPv6
242      * scoped addresses.
243      *
244      * @param host the specified host
245      * @param addr the raw IP address in network byte order
246      * @param nif an interface this address must be associated with.
247      * @return an Inet6Address object created from the raw IP address.
248      * @exception UnknownHostException if IP address is of illegal length, or if the interface
249      * does not have a numeric scope_id assigned for the given address type.
250      *
251      * @since 1.5
252      */

253
254     public static Inet6Address JavaDoc getByAddress(String JavaDoc host, byte[] addr, NetworkInterface JavaDoc nif)
255     throws UnknownHostException JavaDoc {
256     if (host != null && host.length() > 0 && host.charAt(0) == '[') {
257         if (host.charAt(host.length()-1) == ']') {
258         host = host.substring(1, host.length() -1);
259         }
260     }
261     if (addr != null) {
262         if (addr.length == Inet6Address.INADDRSZ) {
263             return new Inet6Address JavaDoc(host, addr, nif);
264         }
265     }
266     throw new UnknownHostException JavaDoc("addr is of illegal length");
267     }
268
269     /**
270      * Create an Inet6Address in the exact manner of {@link InetAddress#getByAddress(String,byte[])}
271      * except that the IPv6 scope_id is set to the given numeric value.
272      * The scope_id is not checked to determine if it corresponds to any interface on the system.
273      * See <a HREF="Inet6Address.html#scoped">here</a> for a description of IPv6
274      * scoped addresses.
275      *
276      * @param host the specified host
277      * @param addr the raw IP address in network byte order
278      * @param scope_id the numeric scope_id for the address.
279      * @return an Inet6Address object created from the raw IP address.
280      * @exception UnknownHostException if IP address is of illegal length.
281      *
282      * @since 1.5
283      */

284
285     public static Inet6Address JavaDoc getByAddress(String JavaDoc host, byte[] addr, int scope_id)
286     throws UnknownHostException JavaDoc {
287     if (host != null && host.length() > 0 && host.charAt(0) == '[') {
288         if (host.charAt(host.length()-1) == ']') {
289         host = host.substring(1, host.length() -1);
290         }
291     }
292     if (addr != null) {
293         if (addr.length == Inet6Address.INADDRSZ) {
294             return new Inet6Address JavaDoc(host, addr, scope_id);
295         }
296     }
297     throw new UnknownHostException JavaDoc("addr is of illegal length");
298     }
299
300     private void initstr (String JavaDoc hostName, byte addr[], String JavaDoc ifname) throws UnknownHostException JavaDoc {
301     try {
302         NetworkInterface JavaDoc nif = NetworkInterface.getByName (ifname);
303         if (nif == null) {
304         throw new UnknownHostException JavaDoc ("no such interface " + ifname);
305         }
306         initif (hostName, addr, nif);
307     } catch (SocketException JavaDoc e) {
308         throw new UnknownHostException JavaDoc ("SocketException thrown" + ifname);
309     }
310     }
311
312     private void initif(String JavaDoc hostName, byte addr[],NetworkInterface JavaDoc nif) throws UnknownHostException JavaDoc {
313     this.hostName = hostName;
314     if (addr.length == INADDRSZ) { // normal IPv6 address
315
family = IPv6;
316         ipaddress = (byte[])addr.clone();
317     }
318     if (nif != null) {
319         this.scope_ifname = nif;
320         scope_ifname_set = true;
321         scope_id = deriveNumericScope (nif);
322         scope_id_set = true;
323     }
324     }
325
326     /* check the two Ipv6 addresses and return false if they are both
327      * non global address types, but not the same.
328      * (ie. one is sitelocal and the other linklocal)
329      * return true otherwise.
330      */

331     private boolean differentLocalAddressTypes(Inet6Address JavaDoc other) {
332
333     if (isLinkLocalAddress() && !other.isLinkLocalAddress()) {
334         return false;
335     }
336     if (isSiteLocalAddress() && !other.isSiteLocalAddress()) {
337         return false;
338     }
339     return true;
340     }
341
342     private int deriveNumericScope (NetworkInterface JavaDoc ifc) throws UnknownHostException JavaDoc {
343     Enumeration JavaDoc addresses = ifc.getInetAddresses();
344     while (addresses.hasMoreElements()) {
345         InetAddress JavaDoc address = (InetAddress JavaDoc)addresses.nextElement();
346         if (!(address instanceof Inet6Address JavaDoc)) {
347         continue;
348         }
349         Inet6Address JavaDoc ia6_addr = (Inet6Address JavaDoc)address;
350         /* check if site or link local prefixes match */
351         if (!differentLocalAddressTypes(ia6_addr)){
352         /* type not the same, so carry on searching */
353         continue;
354         }
355         /* found a matching address - return its scope_id */
356         return ia6_addr.scope_id;
357     }
358     throw new UnknownHostException JavaDoc ("no scope_id found");
359     }
360
361     private int deriveNumericScope (String JavaDoc ifname) throws UnknownHostException JavaDoc {
362     Enumeration JavaDoc en;
363     try {
364         en = NetworkInterface.getNetworkInterfaces();
365     } catch (SocketException JavaDoc e) {
366         throw new UnknownHostException JavaDoc ("could not enumerate local network interfaces");
367     }
368     while (en.hasMoreElements()) {
369         NetworkInterface JavaDoc ifc = (NetworkInterface JavaDoc)en.nextElement();
370         if (ifc.getName().equals (ifname)) {
371         Enumeration JavaDoc addresses = ifc.getInetAddresses();
372         while (addresses.hasMoreElements()) {
373             InetAddress JavaDoc address = (InetAddress JavaDoc)addresses.nextElement();
374             if (!(address instanceof Inet6Address JavaDoc)) {
375             continue;
376             }
377             Inet6Address JavaDoc ia6_addr = (Inet6Address JavaDoc)address;
378             /* check if site or link local prefixes match */
379             if (!differentLocalAddressTypes(ia6_addr)){
380             /* type not the same, so carry on searching */
381             continue;
382             }
383             /* found a matching address - return its scope_id */
384             return ia6_addr.scope_id;
385         }
386         }
387     }
388     throw new UnknownHostException JavaDoc ("No matching address found for interface : " +ifname);
389     }
390
391     /**
392      * restore the state of this object from stream
393      * including the scope information, only if the
394      * scoped interface name is valid on this system
395      */

396     private void readObject(ObjectInputStream JavaDoc s)
397     throws IOException JavaDoc, ClassNotFoundException JavaDoc {
398     scope_ifname = null;
399     scope_ifname_set = false;
400     s.defaultReadObject();
401     
402     if (ifname != null && !"".equals (ifname)) {
403         try {
404         scope_ifname = NetworkInterface.getByName(ifname);
405         try {
406             scope_id = deriveNumericScope (scope_ifname);
407         } catch (UnknownHostException JavaDoc e) {
408             // should not happen
409
assert false;
410         }
411         } catch (SocketException JavaDoc e) {}
412
413         if (scope_ifname == null) {
414             /* the interface does not exist on this system, so we clear
415              * the scope information completely */

416             scope_id_set = false;
417             scope_ifname_set = false;
418             scope_id = 0;
419         }
420     }
421     /* if ifname was not supplied, then the numeric info is used */
422         
423     ipaddress = (byte[])ipaddress.clone();
424
425     // Check that our invariants are satisfied
426
if (ipaddress.length != INADDRSZ) {
427         throw new InvalidObjectException JavaDoc("invalid address length: "+
428                          ipaddress.length);
429     }
430     
431     if (family != IPv6) {
432         throw new InvalidObjectException JavaDoc("invalid address family type");
433     }
434     }
435     
436     /**
437      * Utility routine to check if the InetAddress is an IP multicast
438      * address. 11111111 at the start of the address identifies the
439      * address as being a multicast address.
440      *
441      * @return a <code>boolean</code> indicating if the InetAddress is
442      * an IP multicast address
443      * @since JDK1.1
444      */

445     public boolean isMulticastAddress() {
446     return ((ipaddress[0] & 0xff) == 0xff);
447     }
448
449     /**
450      * Utility routine to check if the InetAddress in a wildcard address.
451      * @return a <code>boolean</code> indicating if the Inetaddress is
452      * a wildcard address.
453      * @since 1.4
454      */

455     public boolean isAnyLocalAddress() {
456     byte test = 0x00;
457     for (int i = 0; i < INADDRSZ; i++) {
458         test |= ipaddress[i];
459     }
460     return (test == 0x00);
461     }
462
463     /**
464      * Utility routine to check if the InetAddress is a loopback address.
465      *
466      * @return a <code>boolean</code> indicating if the InetAddress is
467      * a loopback address; or false otherwise.
468      * @since 1.4
469      */

470     public boolean isLoopbackAddress() {
471     byte test = 0x00;
472     for (int i = 0; i < 15; i++) {
473         test |= ipaddress[i];
474     }
475     return (test == 0x00) && (ipaddress[15] == 0x01);
476     }
477
478     /**
479      * Utility routine to check if the InetAddress is an link local address.
480      *
481      * @return a <code>boolean</code> indicating if the InetAddress is
482      * a link local address; or false if address is not a link local unicast address.
483      * @since 1.4
484      */

485     public boolean isLinkLocalAddress() {
486     return ((ipaddress[0] & 0xff) == 0xfe
487         && (ipaddress[1] & 0xc0) == 0x80);
488     }
489
490     /**
491      * Utility routine to check if the InetAddress is a site local address.
492      *
493      * @return a <code>boolean</code> indicating if the InetAddress is
494      * a site local address; or false if address is not a site local unicast address.
495      * @since 1.4
496      */

497     public boolean isSiteLocalAddress() {
498     return ((ipaddress[0] & 0xff) == 0xfe
499         && (ipaddress[1] & 0xc0) == 0xc0);
500     }
501
502     /**
503      * Utility routine to check if the multicast address has global scope.
504      *
505      * @return a <code>boolean</code> indicating if the address has
506      * is a multicast address of global scope, false if it is not
507      * of global scope or it is not a multicast address
508      * @since 1.4
509      */

510     public boolean isMCGlobal() {
511     return ((ipaddress[0] & 0xff) == 0xff
512         && (ipaddress[1] & 0x0f) == 0x0e);
513     }
514
515     /**
516      * Utility routine to check if the multicast address has node scope.
517      *
518      * @return a <code>boolean</code> indicating if the address has
519      * is a multicast address of node-local scope, false if it is not
520      * of node-local scope or it is not a multicast address
521      * @since 1.4
522      */

523     public boolean isMCNodeLocal() {
524     return ((ipaddress[0] & 0xff) == 0xff
525         && (ipaddress[1] & 0x0f) == 0x01);
526     }
527
528     /**
529      * Utility routine to check if the multicast address has link scope.
530      *
531      * @return a <code>boolean</code> indicating if the address has
532      * is a multicast address of link-local scope, false if it is not
533      * of link-local scope or it is not a multicast address
534      * @since 1.4
535      */

536     public boolean isMCLinkLocal() {
537     return ((ipaddress[0] & 0xff) == 0xff
538         && (ipaddress[1] & 0x0f) == 0x02);
539     }
540
541     /**
542      * Utility routine to check if the multicast address has site scope.
543      *
544      * @return a <code>boolean</code> indicating if the address has
545      * is a multicast address of site-local scope, false if it is not
546      * of site-local scope or it is not a multicast address
547      * @since 1.4
548      */

549     public boolean isMCSiteLocal() {
550     return ((ipaddress[0] & 0xff) == 0xff
551         && (ipaddress[1] & 0x0f) == 0x05);
552     }
553
554     /**
555      * Utility routine to check if the multicast address has organization scope.
556      *
557      * @return a <code>boolean</code> indicating if the address has
558      * is a multicast address of organization-local scope,
559      * false if it is not of organization-local scope
560      * or it is not a multicast address
561      * @since 1.4
562      */

563     public boolean isMCOrgLocal() {
564     return ((ipaddress[0] & 0xff) == 0xff
565         && (ipaddress[1] & 0x0f) == 0x08);
566     }
567
568     /**
569      * Returns the raw IP address of this <code>InetAddress</code>
570      * object. The result is in network byte order: the highest order
571      * byte of the address is in <code>getAddress()[0]</code>.
572      *
573      * @return the raw IP address of this object.
574      */

575     public byte[] getAddress() {
576     return (byte[])ipaddress.clone();
577     }
578
579     /**
580      * Returns the numeric scopeId, if this instance is associated with
581      * an interface. If no scoped_id is set, the returned value is zero.
582      *
583      * @return the scopeId, or zero if not set.
584      * @since 1.5
585      */

586      public int getScopeId () {
587     return scope_id;
588      }
589
590     /**
591      * Returns the scoped interface, if this instance was created with
592      * with a scoped interface.
593      *
594      * @return the scoped interface, or null if not set.
595      * @since 1.5
596      */

597      public NetworkInterface JavaDoc getScopedInterface () {
598     return scope_ifname;
599      }
600
601     /**
602      * Returns the IP address string in textual presentation. If the instance was created
603      * specifying a scope identifier then the scope id is appended to the IP address preceded by
604      * a "%" (per-cent) character. This can be either a numeric value or a string, depending on which
605      * was used to createthe instance.
606      *
607      * @return the raw IP address in a string format.
608      */

609     public String JavaDoc getHostAddress() {
610     String JavaDoc s = numericToTextFormat(ipaddress);
611     if (scope_ifname_set) { /* must check this first */
612         s = s + "%" + scope_ifname.getName();
613     } else if (scope_id_set) {
614         s = s + "%" + scope_id;
615     }
616     return s;
617     }
618
619     /**
620      * Returns a hashcode for this IP address.
621      *
622      * @return a hash code value for this IP address.
623      */

624     public int hashCode() {
625     if (ipaddress != null) {
626
627         int hash = 0;
628         int i=0;
629         while (i<INADDRSZ) {
630         int j=0;
631         int component=0;
632         while (j<4 && i<INADDRSZ) {
633             component = (component << 8) + ipaddress[i];
634             j++;
635             i++;
636         }
637         hash += component;
638         }
639         return hash;
640
641     } else {
642         return 0;
643     }
644     }
645     
646     /**
647      * Compares this object against the specified object.
648      * The result is <code>true</code> if and only if the argument is
649      * not <code>null</code> and it represents the same IP address as
650      * this object.
651      * <p>
652      * Two instances of <code>InetAddress</code> represent the same IP
653      * address if the length of the byte arrays returned by
654      * <code>getAddress</code> is the same for both, and each of the
655      * array components is the same for the byte arrays.
656      *
657      * @param obj the object to compare against.
658      * @return <code>true</code> if the objects are the same;
659      * <code>false</code> otherwise.
660      * @see java.net.InetAddress#getAddress()
661      */

662     public boolean equals(Object JavaDoc obj) {
663     if (obj == null ||
664         !(obj instanceof Inet6Address JavaDoc))
665         return false;
666
667     Inet6Address JavaDoc inetAddr = (Inet6Address JavaDoc)obj;
668
669     for (int i = 0; i < INADDRSZ; i++) {
670         if (ipaddress[i] != inetAddr.ipaddress[i])
671         return false;
672     }
673     
674     return true;
675     }
676
677     /**
678      * Utility routine to check if the InetAddress is an
679      * IPv4 compatible IPv6 address.
680      *
681      * @return a <code>boolean</code> indicating if the InetAddress is
682      * an IPv4 compatible IPv6 address; or false if address is IPv4 address.
683      * @since 1.4
684      */

685     public boolean isIPv4CompatibleAddress() {
686     if ((ipaddress[0] == 0x00) && (ipaddress[1] == 0x00) &&
687         (ipaddress[2] == 0x00) && (ipaddress[3] == 0x00) &&
688         (ipaddress[4] == 0x00) && (ipaddress[5] == 0x00) &&
689         (ipaddress[6] == 0x00) && (ipaddress[7] == 0x00) &&
690         (ipaddress[8] == 0x00) && (ipaddress[9] == 0x00) &&
691         (ipaddress[10] == 0x00) && (ipaddress[11] == 0x00)) {
692         return true;
693     }
694     return false;
695     }
696
697     // Utilities
698
private final static int INT16SZ = 2;
699     /*
700      * Convert IPv6 binary address into presentation (printable) format.
701      *
702      * @param src a byte array representing the IPv6 numeric address
703      * @return a String representing an IPv6 address in
704      * textual representation format
705      * @since 1.4
706      */

707     static String JavaDoc numericToTextFormat(byte[] src)
708     {
709     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(39);
710     for (int i = 0; i < (INADDRSZ / INT16SZ); i++) {
711         sb.append(Integer.toHexString(((src[i<<1]<<8) & 0xff00)
712                       | (src[(i<<1)+1] & 0xff)));
713         if (i < (INADDRSZ / INT16SZ) -1 ) {
714            sb.append(":");
715         }
716     }
717     return sb.toString();
718     }
719
720     /**
721      * Perform class load-time initializations.
722      */

723     private static native void init();
724
725     /**
726      * Following field is only used during (de)/serialization
727      */

728     private String JavaDoc ifname;
729
730     /**
731      * default behavior is overridden in order to write the
732      * scope_ifname field as a String, rather than a NetworkInterface
733      * which is not serializable
734      */

735     private synchronized void writeObject(java.io.ObjectOutputStream JavaDoc s)
736         throws IOException JavaDoc
737     {
738     if (scope_ifname_set) {
739         ifname = scope_ifname.getName();
740     }
741     s.defaultWriteObject();
742     }
743 }
744
745
Popular Tags