1ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff/* 2ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Copyright (C) 2010 The Android Open Source Project 3ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * 4ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License"); 5ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * you may not use this file except in compliance with the License. 6ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * You may obtain a copy of the License at 7ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * 8ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * http://www.apache.org/licenses/LICENSE-2.0 9ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * 10ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Unless required by applicable law or agreed to in writing, software 11ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS, 12ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * See the License for the specific language governing permissions and 14ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * limitations under the License. 15ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 16ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 17ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffpackage android.net; 18ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 19ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport android.os.Parcel; 20ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport android.os.Parcelable; 218c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colittiimport android.util.Pair; 22ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 23b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwaltimport java.net.Inet4Address; 24befe778c73e48417942fc31c06509bac8e5ca0d2Erik Klineimport java.net.Inet6Address; 25ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport java.net.InetAddress; 26ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport java.net.InterfaceAddress; 27ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport java.net.UnknownHostException; 28ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 2934385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport static android.system.OsConstants.IFA_F_DADFAILED; 3034385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport static android.system.OsConstants.IFA_F_DEPRECATED; 31befe778c73e48417942fc31c06509bac8e5ca0d2Erik Klineimport static android.system.OsConstants.IFA_F_OPTIMISTIC; 3234385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport static android.system.OsConstants.IFA_F_TENTATIVE; 3334385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport static android.system.OsConstants.RT_SCOPE_HOST; 3434385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport static android.system.OsConstants.RT_SCOPE_LINK; 3534385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport static android.system.OsConstants.RT_SCOPE_SITE; 3634385d352da19805ae948215e2edbeedd16b7941Elliott Hughesimport static android.system.OsConstants.RT_SCOPE_UNIVERSE; 3764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 38ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff/** 39e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Identifies an IP address on a network link. 4064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * 4164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * A {@code LinkAddress} consists of: 4264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * <ul> 4364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * <li>An IP address and prefix length (e.g., {@code 2001:db8::1/64} or {@code 192.0.2.1/24}). 4464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * The address must be unicast, as multicast addresses cannot be assigned to interfaces. 457dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * <li>Address flags: A bitmask of {@code OsConstants.IFA_F_*} values representing properties 467dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * of the address (e.g., {@code android.system.OsConstants.IFA_F_OPTIMISTIC}). 477dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * <li>Address scope: One of the {@code OsConstants.IFA_F_*} values; defines the scope in which 487dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * the address is unique (e.g., 497dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * {@code android.system.OsConstants.RT_SCOPE_LINK} or 507dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * {@code android.system.OsConstants.RT_SCOPE_UNIVERSE}). 517dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * </ul> 52ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 53ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffpublic class LinkAddress implements Parcelable { 54ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 55ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * IPv4 or IPv6 address. 56ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 576eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti private InetAddress address; 58ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 59ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 60e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Prefix length. 61ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 626eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti private int prefixLength; 63ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 6464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 6564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Address flags. A bitmask of IFA_F_* values. 6664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 6764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti private int flags; 6864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 6964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 7064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Address scope. One of the RT_SCOPE_* constants. 7164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 7264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti private int scope; 7364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 7464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 7564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Utility function to determines the scope of a unicast address. Per RFC 4291 section 2.5 and 7664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * RFC 6724 section 3.2. 7764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @hide 7864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 7964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti static int scopeForUnicastAddress(InetAddress addr) { 8064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti if (addr.isAnyLocalAddress()) { 8164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return RT_SCOPE_HOST; 8264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 8364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 8464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) { 8564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return RT_SCOPE_LINK; 8664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 8764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 8864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti // isSiteLocalAddress() returns true for private IPv4 addresses, but RFC 6724 section 3.2 8964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti // says that they are assigned global scope. 9064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti if (!(addr instanceof Inet4Address) && addr.isSiteLocalAddress()) { 9164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return RT_SCOPE_SITE; 9264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 9364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 9464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return RT_SCOPE_UNIVERSE; 9564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 9664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 9764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 98befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * Utility function to check if |address| is a Unique Local IPv6 Unicast Address 99befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * (a.k.a. "ULA"; RFC 4193). 100befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * 101befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * Per RFC 4193 section 8, fc00::/7 identifies these addresses. 102befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline */ 103befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline private boolean isIPv6ULA() { 104befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline if (address != null && address instanceof Inet6Address) { 105befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline byte[] bytes = address.getAddress(); 106befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline return ((bytes[0] & (byte)0xfc) == (byte)0xfc); 107befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline } 108befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline return false; 109befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline } 110befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline 111befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline /** 11264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Utility function for the constructors. 11364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 11464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti private void init(InetAddress address, int prefixLength, int flags, int scope) { 11564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti if (address == null || 11664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti address.isMulticastAddress() || 11764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti prefixLength < 0 || 118b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt ((address instanceof Inet4Address) && prefixLength > 32) || 119b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt (prefixLength > 128)) { 120b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt throw new IllegalArgumentException("Bad LinkAddress params " + address + 1216eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti "/" + prefixLength); 122b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt } 123ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff this.address = address; 12496ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff this.prefixLength = prefixLength; 12564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.flags = flags; 12664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.scope = scope; 12764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 12864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 12964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 13064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with 13164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * the specified flags and scope. Flags and scope are not checked for validity. 13264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param address The IP address. 13364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param prefixLength The prefix length. 134fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address. 135fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @param scope An integer defining the scope in which the address is unique (e.g., 136fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}). 137fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 13864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 13964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public LinkAddress(InetAddress address, int prefixLength, int flags, int scope) { 14064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti init(address, prefixLength, flags, scope); 141ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 142ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 143e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti /** 144e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length. 14564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * The flags are set to zero and the scope is determined from the address. 146e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * @param address The IP address. 147e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * @param prefixLength The prefix length. 148fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 149e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti */ 1506eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti public LinkAddress(InetAddress address, int prefixLength) { 15164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this(address, prefixLength, 0, 0); 15264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.scope = scopeForUnicastAddress(address); 1536eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } 1546eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti 155e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti /** 156e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Constructs a new {@code LinkAddress} from an {@code InterfaceAddress}. 15764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * The flags are set to zero and the scope is determined from the address. 158e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * @param interfaceAddress The interface address. 159fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 160e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti */ 161ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public LinkAddress(InterfaceAddress interfaceAddress) { 16264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this(interfaceAddress.getAddress(), 1636eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti interfaceAddress.getNetworkPrefixLength()); 1646eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } 1656eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti 1666eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti /** 1676eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or 16864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * "2001:db8::1/64". The flags are set to zero and the scope is determined from the address. 1696eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti * @param string The string to parse. 170fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 1716eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti */ 1726eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti public LinkAddress(String address) { 17364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this(address, 0, 0); 17464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.scope = scopeForUnicastAddress(this.address); 17564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 17664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 17764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 17864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or 17964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * "2001:db8::1/64", with the specified flags and scope. 18064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param string The string to parse. 18164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param flags The address flags. 18264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param scope The address scope. 183fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 18464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 18564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public LinkAddress(String address, int flags, int scope) { 1868c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti // This may throw an IllegalArgumentException; catching it is the caller's responsibility. 1878c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(address); 1888c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti init(ipAndMask.first, ipAndMask.second, flags, scope); 189ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 190ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 19164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 19264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Returns a string representation of this address, such as "192.0.2.1/24" or "2001:db8::1/64". 19364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * The string representation does not contain the flags and scope, just the address and prefix 19464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * length. 19564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 196ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff @Override 197ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public String toString() { 198e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti return address.getHostAddress() + "/" + prefixLength; 199ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 200ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 201ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 20264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Compares this {@code LinkAddress} instance against {@code obj}. Two addresses are equal if 2037dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * their address, prefix length, flags and scope are equal. Thus, for example, two addresses 2047dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * that have the same address and prefix length are not equal if one of them is deprecated and 2057dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * the other is not. 206ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * 207ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @param obj the object to be tested for equality. 208ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @return {@code true} if both objects are equal, {@code false} otherwise. 209ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 210ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff @Override 211ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public boolean equals(Object obj) { 212ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff if (!(obj instanceof LinkAddress)) { 213ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return false; 214ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 215ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff LinkAddress linkAddress = (LinkAddress) obj; 216ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return this.address.equals(linkAddress.address) && 21764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.prefixLength == linkAddress.prefixLength && 21864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.flags == linkAddress.flags && 21964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.scope == linkAddress.scope; 220ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 221ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 222e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti /** 223e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Returns a hashcode for this address. 2244e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang */ 225e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti @Override 2264e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang public int hashCode() { 22764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return address.hashCode() + 11 * prefixLength + 19 * flags + 43 * scope; 22864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 22964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 23064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 231fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Determines whether this {@code LinkAddress} and the provided {@code LinkAddress} 232fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * represent the same address. Two {@code LinkAddresses} represent the same address 233fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * if they have the same IP address and prefix length, even if their properties are 234fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * different. 23564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * 23664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param other the {@code LinkAddress} to compare to. 23764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @return {@code true} if both objects have the same address and prefix length, {@code false} 23864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * otherwise. 2397dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * @hide 24064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 24164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public boolean isSameAddressAs(LinkAddress other) { 24264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return address.equals(other.address) && prefixLength == other.prefixLength; 2434e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang } 2444e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang 245ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 246fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Returns the {@link InetAddress} of this {@code LinkAddress}. 247ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 248ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public InetAddress getAddress() { 249ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return address; 250ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 251ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 252ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 253fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Returns the prefix length of this {@code LinkAddress}. 254ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 2557dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti public int getPrefixLength() { 25696ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff return prefixLength; 257ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 258ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 259ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 2607dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * Returns the prefix length of this {@code LinkAddress}. 2617dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * TODO: Delete all callers and remove in favour of getPrefixLength(). 2627dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * @hide 2637dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti */ 2647dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti public int getNetworkPrefixLength() { 2657dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti return getPrefixLength(); 2667dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti } 2677dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti 2687dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti /** 269fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Returns the flags of this {@code LinkAddress}. 27064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 27164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public int getFlags() { 27264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return flags; 27364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 27464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 27564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 276fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Returns the scope of this {@code LinkAddress}. 27764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 27864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public int getScope() { 27964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return scope; 28064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 28164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 28264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 28364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Returns true if this {@code LinkAddress} is global scope and preferred. 284fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 28564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 28664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public boolean isGlobalPreferred() { 287befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline /** 288befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * Note that addresses flagged as IFA_F_OPTIMISTIC are 289befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * simultaneously flagged as IFA_F_TENTATIVE (when the tentative 290befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * state has cleared either DAD has succeeded or failed, and both 291befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * flags are cleared regardless). 292befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline */ 29364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return (scope == RT_SCOPE_UNIVERSE && 294befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline !isIPv6ULA() && 295befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L && 296befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline ((flags & IFA_F_TENTATIVE) == 0L || (flags & IFA_F_OPTIMISTIC) != 0L)); 29764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 29864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 29964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 300e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Implement the Parcelable interface. 301ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 302ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public int describeContents() { 303ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return 0; 304ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 305ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 306ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 307ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Implement the Parcelable interface. 308ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 309ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public void writeToParcel(Parcel dest, int flags) { 310e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti dest.writeByteArray(address.getAddress()); 311e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti dest.writeInt(prefixLength); 31264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti dest.writeInt(this.flags); 31364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti dest.writeInt(scope); 314ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 315ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 316ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 317ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Implement the Parcelable interface. 318ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 319ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public static final Creator<LinkAddress> CREATOR = 320ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff new Creator<LinkAddress>() { 321ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public LinkAddress createFromParcel(Parcel in) { 322ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff InetAddress address = null; 323e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti try { 324e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti address = InetAddress.getByAddress(in.createByteArray()); 325e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti } catch (UnknownHostException e) { 326e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti // Nothing we can do here. When we call the constructor, we'll throw an 327e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti // IllegalArgumentException, because a LinkAddress can't have a null 328e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti // InetAddress. 329ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 330e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti int prefixLength = in.readInt(); 33164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti int flags = in.readInt(); 33264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti int scope = in.readInt(); 33364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return new LinkAddress(address, prefixLength, flags, scope); 334ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 335ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 336ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public LinkAddress[] newArray(int size) { 337ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return new LinkAddress[size]; 338ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 339ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff }; 340ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff} 341