Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/net/Inet6Address.java
38829 views
/*1* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.net;2627import java.io.IOException;28import java.io.InvalidObjectException;29import java.io.ObjectInputStream;30import java.io.ObjectOutputStream;31import java.io.ObjectStreamField;32import java.util.Enumeration;33import java.util.Arrays;3435/**36* This class represents an Internet Protocol version 6 (IPv6) address.37* Defined by <a href="http://www.ietf.org/rfc/rfc2373.txt">38* <i>RFC 2373: IP Version 6 Addressing Architecture</i></a>.39*40* <h3> <A NAME="format">Textual representation of IP addresses</a> </h3>41*42* Textual representation of IPv6 address used as input to methods43* takes one of the following forms:44*45* <ol>46* <li><p> <A NAME="lform">The preferred form</a> is x:x:x:x:x:x:x:x,47* where the 'x's are48* the hexadecimal values of the eight 16-bit pieces of the49* address. This is the full form. For example,50*51* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">52* <tr><td>{@code 1080:0:0:0:8:800:200C:417A}<td></tr>53* </table></blockquote>54*55* <p> Note that it is not necessary to write the leading zeros in56* an individual field. However, there must be at least one numeral57* in every field, except as described below.</li>58*59* <li><p> Due to some methods of allocating certain styles of IPv660* addresses, it will be common for addresses to contain long61* strings of zero bits. In order to make writing addresses62* containing zero bits easier, a special syntax is available to63* compress the zeros. The use of "::" indicates multiple groups64* of 16-bits of zeros. The "::" can only appear once in an address.65* The "::" can also be used to compress the leading and/or trailing66* zeros in an address. For example,67*68* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">69* <tr><td>{@code 1080::8:800:200C:417A}<td></tr>70* </table></blockquote>71*72* <li><p> An alternative form that is sometimes more convenient73* when dealing with a mixed environment of IPv4 and IPv6 nodes is74* x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values75* of the six high-order 16-bit pieces of the address, and the 'd's76* are the decimal values of the four low-order 8-bit pieces of the77* standard IPv4 representation address, for example,78*79* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">80* <tr><td>{@code ::FFFF:129.144.52.38}<td></tr>81* <tr><td>{@code ::129.144.52.38}<td></tr>82* </table></blockquote>83*84* <p> where "::FFFF:d.d.d.d" and "::d.d.d.d" are, respectively, the85* general forms of an IPv4-mapped IPv6 address and an86* IPv4-compatible IPv6 address. Note that the IPv4 portion must be87* in the "d.d.d.d" form. The following forms are invalid:88*89* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">90* <tr><td>{@code ::FFFF:d.d.d}<td></tr>91* <tr><td>{@code ::FFFF:d.d}<td></tr>92* <tr><td>{@code ::d.d.d}<td></tr>93* <tr><td>{@code ::d.d}<td></tr>94* </table></blockquote>95*96* <p> The following form:97*98* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">99* <tr><td>{@code ::FFFF:d}<td></tr>100* </table></blockquote>101*102* <p> is valid, however it is an unconventional representation of103* the IPv4-compatible IPv6 address,104*105* <blockquote><table cellpadding=0 cellspacing=0 summary="layout">106* <tr><td>{@code ::255.255.0.d}<td></tr>107* </table></blockquote>108*109* <p> while "::d" corresponds to the general IPv6 address110* "0:0:0:0:0:0:0:d".</li>111* </ol>112*113* <p> For methods that return a textual representation as output114* value, the full form is used. Inet6Address will return the full115* form because it is unambiguous when used in combination with other116* textual data.117*118* <h4> Special IPv6 address </h4>119*120* <blockquote>121* <table cellspacing=2 summary="Description of IPv4-mapped address">122* <tr><th valign=top><i>IPv4-mapped address</i></th>123* <td>Of the form::ffff:w.x.y.z, this IPv6 address is used to124* represent an IPv4 address. It allows the native program to125* use the same address data structure and also the same126* socket when communicating with both IPv4 and IPv6 nodes.127*128* <p>In InetAddress and Inet6Address, it is used for internal129* representation; it has no functional role. Java will never130* return an IPv4-mapped address. These classes can take an131* IPv4-mapped address as input, both in byte array and text132* representation. However, it will be converted into an IPv4133* address.</td></tr>134* </table></blockquote>135*136* <h4><A NAME="scoped">Textual representation of IPv6 scoped addresses</a></h4>137*138* <p> The textual representation of IPv6 addresses as described above can be139* extended to specify IPv6 scoped addresses. This extension to the basic140* addressing architecture is described in [draft-ietf-ipngwg-scoping-arch-04.txt].141*142* <p> Because link-local and site-local addresses are non-global, it is possible143* that different hosts may have the same destination address and may be144* reachable through different interfaces on the same originating system. In145* this case, the originating system is said to be connected to multiple zones146* of the same scope. In order to disambiguate which is the intended destination147* zone, it is possible to append a zone identifier (or <i>scope_id</i>) to an148* IPv6 address.149*150* <p> The general format for specifying the <i>scope_id</i> is the following:151*152* <blockquote><i>IPv6-address</i>%<i>scope_id</i></blockquote>153* <p> The IPv6-address is a literal IPv6 address as described above.154* The <i>scope_id</i> refers to an interface on the local system, and it can be155* specified in two ways.156* <ol><li><i>As a numeric identifier.</i> This must be a positive integer157* that identifies the particular interface and scope as understood by the158* system. Usually, the numeric values can be determined through administration159* tools on the system. Each interface may have multiple values, one for each160* scope. If the scope is unspecified, then the default value used is zero.</li>161* <li><i>As a string.</i> This must be the exact string that is returned by162* {@link java.net.NetworkInterface#getName()} for the particular interface in163* question. When an Inet6Address is created in this way, the numeric scope-id164* is determined at the time the object is created by querying the relevant165* NetworkInterface.</li></ol>166*167* <p> Note also, that the numeric <i>scope_id</i> can be retrieved from168* Inet6Address instances returned from the NetworkInterface class. This can be169* used to find out the current scope ids configured on the system.170* @since 1.4171*/172173public final174class Inet6Address extends InetAddress {175final static int INADDRSZ = 16;176177/*178* cached scope_id - for link-local address use only.179*/180private transient int cached_scope_id; // 0181182private class Inet6AddressHolder {183184private Inet6AddressHolder() {185ipaddress = new byte[INADDRSZ];186}187188private Inet6AddressHolder(189byte[] ipaddress, int scope_id, boolean scope_id_set,190NetworkInterface ifname, boolean scope_ifname_set)191{192this.ipaddress = ipaddress;193this.scope_id = scope_id;194this.scope_id_set = scope_id_set;195this.scope_ifname_set = scope_ifname_set;196this.scope_ifname = ifname;197}198199/**200* Holds a 128-bit (16 bytes) IPv6 address.201*/202byte[] ipaddress;203204/**205* scope_id. The scope specified when the object is created. If the object206* is created with an interface name, then the scope_id is not determined207* until the time it is needed.208*/209int scope_id; // 0210211/**212* This will be set to true when the scope_id field contains a valid213* integer scope_id.214*/215boolean scope_id_set; // false216217/**218* scoped interface. scope_id is derived from this as the scope_id of the first219* address whose scope is the same as this address for the named interface.220*/221NetworkInterface scope_ifname; // null222223/**224* set if the object is constructed with a scoped225* interface instead of a numeric scope id.226*/227boolean scope_ifname_set; // false;228229void setAddr(byte addr[]) {230if (addr.length == INADDRSZ) { // normal IPv6 address231System.arraycopy(addr, 0, ipaddress, 0, INADDRSZ);232}233}234235void init(byte addr[], int scope_id) {236setAddr(addr);237238if (scope_id >= 0) {239this.scope_id = scope_id;240this.scope_id_set = true;241}242}243244void init(byte addr[], NetworkInterface nif)245throws UnknownHostException246{247setAddr(addr);248249if (nif != null) {250this.scope_id = deriveNumericScope(ipaddress, nif);251this.scope_id_set = true;252this.scope_ifname = nif;253this.scope_ifname_set = true;254}255}256257String getHostAddress() {258String s = numericToTextFormat(ipaddress);259if (scope_ifname != null) { /* must check this first */260s = s + "%" + scope_ifname.getName();261} else if (scope_id_set) {262s = s + "%" + scope_id;263}264return s;265}266267public boolean equals(Object o) {268if (! (o instanceof Inet6AddressHolder)) {269return false;270}271Inet6AddressHolder that = (Inet6AddressHolder)o;272273return Arrays.equals(this.ipaddress, that.ipaddress);274}275276public int hashCode() {277if (ipaddress != null) {278279int hash = 0;280int i=0;281while (i<INADDRSZ) {282int j=0;283int component=0;284while (j<4 && i<INADDRSZ) {285component = (component << 8) + ipaddress[i];286j++;287i++;288}289hash += component;290}291return hash;292293} else {294return 0;295}296}297298boolean isIPv4CompatibleAddress() {299if ((ipaddress[0] == 0x00) && (ipaddress[1] == 0x00) &&300(ipaddress[2] == 0x00) && (ipaddress[3] == 0x00) &&301(ipaddress[4] == 0x00) && (ipaddress[5] == 0x00) &&302(ipaddress[6] == 0x00) && (ipaddress[7] == 0x00) &&303(ipaddress[8] == 0x00) && (ipaddress[9] == 0x00) &&304(ipaddress[10] == 0x00) && (ipaddress[11] == 0x00)) {305return true;306}307return false;308}309310boolean isMulticastAddress() {311return ((ipaddress[0] & 0xff) == 0xff);312}313314boolean isAnyLocalAddress() {315byte test = 0x00;316for (int i = 0; i < INADDRSZ; i++) {317test |= ipaddress[i];318}319return (test == 0x00);320}321322boolean isLoopbackAddress() {323byte test = 0x00;324for (int i = 0; i < 15; i++) {325test |= ipaddress[i];326}327return (test == 0x00) && (ipaddress[15] == 0x01);328}329330boolean isLinkLocalAddress() {331return ((ipaddress[0] & 0xff) == 0xfe332&& (ipaddress[1] & 0xc0) == 0x80);333}334335336boolean isSiteLocalAddress() {337return ((ipaddress[0] & 0xff) == 0xfe338&& (ipaddress[1] & 0xc0) == 0xc0);339}340341boolean isMCGlobal() {342return ((ipaddress[0] & 0xff) == 0xff343&& (ipaddress[1] & 0x0f) == 0x0e);344}345346boolean isMCNodeLocal() {347return ((ipaddress[0] & 0xff) == 0xff348&& (ipaddress[1] & 0x0f) == 0x01);349}350351boolean isMCLinkLocal() {352return ((ipaddress[0] & 0xff) == 0xff353&& (ipaddress[1] & 0x0f) == 0x02);354}355356boolean isMCSiteLocal() {357return ((ipaddress[0] & 0xff) == 0xff358&& (ipaddress[1] & 0x0f) == 0x05);359}360361boolean isMCOrgLocal() {362return ((ipaddress[0] & 0xff) == 0xff363&& (ipaddress[1] & 0x0f) == 0x08);364}365}366367private final transient Inet6AddressHolder holder6;368369private static final long serialVersionUID = 6880410070516793377L;370371// Perform native initialization372static { init(); }373374Inet6Address() {375super();376holder.init(null, IPv6);377holder6 = new Inet6AddressHolder();378}379380/* checking of value for scope_id should be done by caller381* scope_id must be >= 0, or -1 to indicate not being set382*/383Inet6Address(String hostName, byte addr[], int scope_id) {384holder.init(hostName, IPv6);385holder6 = new Inet6AddressHolder();386holder6.init(addr, scope_id);387}388389Inet6Address(String hostName, byte addr[]) {390holder6 = new Inet6AddressHolder();391try {392initif (hostName, addr, null);393} catch (UnknownHostException e) {} /* cant happen if ifname is null */394}395396Inet6Address (String hostName, byte addr[], NetworkInterface nif)397throws UnknownHostException398{399holder6 = new Inet6AddressHolder();400initif (hostName, addr, nif);401}402403Inet6Address (String hostName, byte addr[], String ifname)404throws UnknownHostException405{406holder6 = new Inet6AddressHolder();407initstr (hostName, addr, ifname);408}409410/**411* Create an Inet6Address in the exact manner of {@link412* InetAddress#getByAddress(String,byte[])} except that the IPv6 scope_id is413* set to the value corresponding to the given interface for the address414* type specified in {@code addr}. The call will fail with an415* UnknownHostException if the given interface does not have a numeric416* scope_id assigned for the given address type (eg. link-local or site-local).417* See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6418* scoped addresses.419*420* @param host the specified host421* @param addr the raw IP address in network byte order422* @param nif an interface this address must be associated with.423* @return an Inet6Address object created from the raw IP address.424* @throws UnknownHostException425* if IP address is of illegal length, or if the interface does not426* have a numeric scope_id assigned for the given address type.427*428* @since 1.5429*/430public static Inet6Address getByAddress(String host, byte[] addr,431NetworkInterface nif)432throws UnknownHostException433{434if (host != null && host.length() > 0 && host.charAt(0) == '[') {435if (host.charAt(host.length()-1) == ']') {436host = host.substring(1, host.length() -1);437}438}439if (addr != null) {440if (addr.length == Inet6Address.INADDRSZ) {441return new Inet6Address(host, addr, nif);442}443}444throw new UnknownHostException("addr is of illegal length");445}446447/**448* Create an Inet6Address in the exact manner of {@link449* InetAddress#getByAddress(String,byte[])} except that the IPv6 scope_id is450* set to the given numeric value. The scope_id is not checked to determine451* if it corresponds to any interface on the system.452* See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6453* scoped addresses.454*455* @param host the specified host456* @param addr the raw IP address in network byte order457* @param scope_id the numeric scope_id for the address.458* @return an Inet6Address object created from the raw IP address.459* @throws UnknownHostException if IP address is of illegal length.460*461* @since 1.5462*/463public static Inet6Address getByAddress(String host, byte[] addr,464int scope_id)465throws UnknownHostException466{467if (host != null && host.length() > 0 && host.charAt(0) == '[') {468if (host.charAt(host.length()-1) == ']') {469host = host.substring(1, host.length() -1);470}471}472if (addr != null) {473if (addr.length == Inet6Address.INADDRSZ) {474return new Inet6Address(host, addr, scope_id);475}476}477throw new UnknownHostException("addr is of illegal length");478}479480private void initstr(String hostName, byte addr[], String ifname)481throws UnknownHostException482{483try {484NetworkInterface nif = NetworkInterface.getByName (ifname);485if (nif == null) {486throw new UnknownHostException ("no such interface " + ifname);487}488initif (hostName, addr, nif);489} catch (SocketException e) {490throw new UnknownHostException ("SocketException thrown" + ifname);491}492}493494private void initif(String hostName, byte addr[], NetworkInterface nif)495throws UnknownHostException496{497int family = -1;498holder6.init(addr, nif);499500if (addr.length == INADDRSZ) { // normal IPv6 address501family = IPv6;502}503holder.init(hostName, family);504}505506/* check the two Ipv6 addresses and return false if they are both507* non global address types, but not the same.508* (ie. one is sitelocal and the other linklocal)509* return true otherwise.510*/511512private static boolean isDifferentLocalAddressType(513byte[] thisAddr, byte[] otherAddr) {514515if (Inet6Address.isLinkLocalAddress(thisAddr) &&516!Inet6Address.isLinkLocalAddress(otherAddr)) {517return false;518}519if (Inet6Address.isSiteLocalAddress(thisAddr) &&520!Inet6Address.isSiteLocalAddress(otherAddr)) {521return false;522}523return true;524}525526private static int deriveNumericScope (byte[] thisAddr, NetworkInterface ifc) throws UnknownHostException {527Enumeration<InetAddress> addresses = ifc.getInetAddresses();528while (addresses.hasMoreElements()) {529InetAddress addr = addresses.nextElement();530if (!(addr instanceof Inet6Address)) {531continue;532}533Inet6Address ia6_addr = (Inet6Address)addr;534/* check if site or link local prefixes match */535if (!isDifferentLocalAddressType(thisAddr, ia6_addr.getAddress())){536/* type not the same, so carry on searching */537continue;538}539/* found a matching address - return its scope_id */540return ia6_addr.getScopeId();541}542throw new UnknownHostException ("no scope_id found");543}544545private int deriveNumericScope (String ifname) throws UnknownHostException {546Enumeration<NetworkInterface> en;547try {548en = NetworkInterface.getNetworkInterfaces();549} catch (SocketException e) {550throw new UnknownHostException ("could not enumerate local network interfaces");551}552while (en.hasMoreElements()) {553NetworkInterface ifc = en.nextElement();554if (ifc.getName().equals (ifname)) {555return deriveNumericScope(holder6.ipaddress, ifc);556}557}558throw new UnknownHostException ("No matching address found for interface : " +ifname);559}560561/**562* @serialField ipaddress byte[]563* @serialField scope_id int564* @serialField scope_id_set boolean565* @serialField scope_ifname_set boolean566* @serialField ifname String567*/568569private static final ObjectStreamField[] serialPersistentFields = {570new ObjectStreamField("ipaddress", byte[].class),571new ObjectStreamField("scope_id", int.class),572new ObjectStreamField("scope_id_set", boolean.class),573new ObjectStreamField("scope_ifname_set", boolean.class),574new ObjectStreamField("ifname", String.class)575};576577private static final long FIELDS_OFFSET;578private static final sun.misc.Unsafe UNSAFE;579580static {581try {582sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();583FIELDS_OFFSET = unsafe.objectFieldOffset(584Inet6Address.class.getDeclaredField("holder6"));585UNSAFE = unsafe;586} catch (ReflectiveOperationException e) {587throw new Error(e);588}589}590591/**592* restore the state of this object from stream593* including the scope information, only if the594* scoped interface name is valid on this system595*/596private void readObject(ObjectInputStream s)597throws IOException, ClassNotFoundException {598NetworkInterface scope_ifname = null;599600if (getClass().getClassLoader() != null) {601throw new SecurityException ("invalid address type");602}603604ObjectInputStream.GetField gf = s.readFields();605byte[] ipaddress = (byte[])gf.get("ipaddress", null);606int scope_id = (int)gf.get("scope_id", -1);607boolean scope_id_set = (boolean)gf.get("scope_id_set", false);608boolean scope_ifname_set = (boolean)gf.get("scope_ifname_set", false);609String ifname = (String)gf.get("ifname", null);610611if (ifname != null && !"".equals (ifname)) {612try {613scope_ifname = NetworkInterface.getByName(ifname);614if (scope_ifname == null) {615/* the interface does not exist on this system, so we clear616* the scope information completely */617scope_id_set = false;618scope_ifname_set = false;619scope_id = 0;620} else {621scope_ifname_set = true;622try {623scope_id = deriveNumericScope (ipaddress, scope_ifname);624} catch (UnknownHostException e) {625// typically should not happen, but it may be that626// the machine being used for deserialization has627// the same interface name but without IPv6 configured.628}629}630} catch (SocketException e) {}631}632633/* if ifname was not supplied, then the numeric info is used */634635ipaddress = ipaddress.clone();636637// Check that our invariants are satisfied638if (ipaddress.length != INADDRSZ) {639throw new InvalidObjectException("invalid address length: "+640ipaddress.length);641}642643if (holder.getFamily() != IPv6) {644throw new InvalidObjectException("invalid address family type");645}646647Inet6AddressHolder h = new Inet6AddressHolder(648ipaddress, scope_id, scope_id_set, scope_ifname, scope_ifname_set649);650651UNSAFE.putObject(this, FIELDS_OFFSET, h);652}653654/**655* default behavior is overridden in order to write the656* scope_ifname field as a String, rather than a NetworkInterface657* which is not serializable658*/659private synchronized void writeObject(ObjectOutputStream s)660throws IOException661{662String ifname = null;663664if (holder6.scope_ifname != null) {665ifname = holder6.scope_ifname.getName();666holder6.scope_ifname_set = true;667}668ObjectOutputStream.PutField pfields = s.putFields();669pfields.put("ipaddress", holder6.ipaddress);670pfields.put("scope_id", holder6.scope_id);671pfields.put("scope_id_set", holder6.scope_id_set);672pfields.put("scope_ifname_set", holder6.scope_ifname_set);673pfields.put("ifname", ifname);674s.writeFields();675}676677/**678* Utility routine to check if the InetAddress is an IP multicast679* address. 11111111 at the start of the address identifies the680* address as being a multicast address.681*682* @return a {@code boolean} indicating if the InetAddress is an IP683* multicast address684*685* @since JDK1.1686*/687@Override688public boolean isMulticastAddress() {689return holder6.isMulticastAddress();690}691692/**693* Utility routine to check if the InetAddress in a wildcard address.694*695* @return a {@code boolean} indicating if the Inetaddress is696* a wildcard address.697*698* @since 1.4699*/700@Override701public boolean isAnyLocalAddress() {702return holder6.isAnyLocalAddress();703}704705/**706* Utility routine to check if the InetAddress is a loopback address.707*708* @return a {@code boolean} indicating if the InetAddress is a loopback709* address; or false otherwise.710*711* @since 1.4712*/713@Override714public boolean isLoopbackAddress() {715return holder6.isLoopbackAddress();716}717718/**719* Utility routine to check if the InetAddress is an link local address.720*721* @return a {@code boolean} indicating if the InetAddress is a link local722* address; or false if address is not a link local unicast address.723*724* @since 1.4725*/726@Override727public boolean isLinkLocalAddress() {728return holder6.isLinkLocalAddress();729}730731/* static version of above */732static boolean isLinkLocalAddress(byte[] ipaddress) {733return ((ipaddress[0] & 0xff) == 0xfe734&& (ipaddress[1] & 0xc0) == 0x80);735}736737/**738* Utility routine to check if the InetAddress is a site local address.739*740* @return a {@code boolean} indicating if the InetAddress is a site local741* address; or false if address is not a site local unicast address.742*743* @since 1.4744*/745@Override746public boolean isSiteLocalAddress() {747return holder6.isSiteLocalAddress();748}749750/* static version of above */751static boolean isSiteLocalAddress(byte[] ipaddress) {752return ((ipaddress[0] & 0xff) == 0xfe753&& (ipaddress[1] & 0xc0) == 0xc0);754}755756/**757* Utility routine to check if the multicast address has global scope.758*759* @return a {@code boolean} indicating if the address has is a multicast760* address of global scope, false if it is not of global scope or761* it is not a multicast address762*763* @since 1.4764*/765@Override766public boolean isMCGlobal() {767return holder6.isMCGlobal();768}769770/**771* Utility routine to check if the multicast address has node scope.772*773* @return a {@code boolean} indicating if the address has is a multicast774* address of node-local scope, false if it is not of node-local775* scope or it is not a multicast address776*777* @since 1.4778*/779@Override780public boolean isMCNodeLocal() {781return holder6.isMCNodeLocal();782}783784/**785* Utility routine to check if the multicast address has link scope.786*787* @return a {@code boolean} indicating if the address has is a multicast788* address of link-local scope, false if it is not of link-local789* scope or it is not a multicast address790*791* @since 1.4792*/793@Override794public boolean isMCLinkLocal() {795return holder6.isMCLinkLocal();796}797798/**799* Utility routine to check if the multicast address has site scope.800*801* @return a {@code boolean} indicating if the address has is a multicast802* address of site-local scope, false if it is not of site-local803* scope or it is not a multicast address804*805* @since 1.4806*/807@Override808public boolean isMCSiteLocal() {809return holder6.isMCSiteLocal();810}811812/**813* Utility routine to check if the multicast address has organization scope.814*815* @return a {@code boolean} indicating if the address has is a multicast816* address of organization-local scope, false if it is not of817* organization-local scope or it is not a multicast address818*819* @since 1.4820*/821@Override822public boolean isMCOrgLocal() {823return holder6.isMCOrgLocal();824}825/**826* Returns the raw IP address of this {@code InetAddress} object. The result827* is in network byte order: the highest order byte of the address is in828* {@code getAddress()[0]}.829*830* @return the raw IP address of this object.831*/832@Override833public byte[] getAddress() {834return holder6.ipaddress.clone();835}836837/**838* Returns the numeric scopeId, if this instance is associated with839* an interface. If no scoped_id is set, the returned value is zero.840*841* @return the scopeId, or zero if not set.842*843* @since 1.5844*/845public int getScopeId() {846return holder6.scope_id;847}848849/**850* Returns the scoped interface, if this instance was created with851* with a scoped interface.852*853* @return the scoped interface, or null if not set.854* @since 1.5855*/856public NetworkInterface getScopedInterface() {857return holder6.scope_ifname;858}859860/**861* Returns the IP address string in textual presentation. If the instance862* was created specifying a scope identifier then the scope id is appended863* to the IP address preceded by a "%" (per-cent) character. This can be864* either a numeric value or a string, depending on which was used to create865* the instance.866*867* @return the raw IP address in a string format.868*/869@Override870public String getHostAddress() {871return holder6.getHostAddress();872}873874/**875* Returns a hashcode for this IP address.876*877* @return a hash code value for this IP address.878*/879@Override880public int hashCode() {881return holder6.hashCode();882}883884/**885* Compares this object against the specified object. The result is {@code886* true} if and only if the argument is not {@code null} and it represents887* the same IP address as this object.888*889* <p> Two instances of {@code InetAddress} represent the same IP address890* if the length of the byte arrays returned by {@code getAddress} is the891* same for both, and each of the array components is the same for the byte892* arrays.893*894* @param obj the object to compare against.895*896* @return {@code true} if the objects are the same; {@code false} otherwise.897*898* @see java.net.InetAddress#getAddress()899*/900@Override901public boolean equals(Object obj) {902if (obj == null || !(obj instanceof Inet6Address))903return false;904905Inet6Address inetAddr = (Inet6Address)obj;906907return holder6.equals(inetAddr.holder6);908}909910/**911* Utility routine to check if the InetAddress is an912* IPv4 compatible IPv6 address.913*914* @return a {@code boolean} indicating if the InetAddress is an IPv4915* compatible IPv6 address; or false if address is IPv4 address.916*917* @since 1.4918*/919public boolean isIPv4CompatibleAddress() {920return holder6.isIPv4CompatibleAddress();921}922923// Utilities924private final static int INT16SZ = 2;925926/*927* Convert IPv6 binary address into presentation (printable) format.928*929* @param src a byte array representing the IPv6 numeric address930* @return a String representing an IPv6 address in931* textual representation format932* @since 1.4933*/934static String numericToTextFormat(byte[] src) {935StringBuilder sb = new StringBuilder(39);936for (int i = 0; i < (INADDRSZ / INT16SZ); i++) {937sb.append(Integer.toHexString(((src[i<<1]<<8) & 0xff00)938| (src[(i<<1)+1] & 0xff)));939if (i < (INADDRSZ / INT16SZ) -1 ) {940sb.append(":");941}942}943return sb.toString();944}945946/**947* Perform class load-time initializations.948*/949private static native void init();950}951952953