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 19fd31b9d46ea09dc7d74ddc03ab7e5ecfbe80b3dcHugo Benichiimport static android.system.OsConstants.IFA_F_DADFAILED; 20fd31b9d46ea09dc7d74ddc03ab7e5ecfbe80b3dcHugo Benichiimport static android.system.OsConstants.IFA_F_DEPRECATED; 21fd31b9d46ea09dc7d74ddc03ab7e5ecfbe80b3dcHugo Benichiimport static android.system.OsConstants.IFA_F_OPTIMISTIC; 22fd31b9d46ea09dc7d74ddc03ab7e5ecfbe80b3dcHugo Benichiimport static android.system.OsConstants.IFA_F_TENTATIVE; 23fd31b9d46ea09dc7d74ddc03ab7e5ecfbe80b3dcHugo Benichiimport static android.system.OsConstants.RT_SCOPE_HOST; 24fd31b9d46ea09dc7d74ddc03ab7e5ecfbe80b3dcHugo Benichiimport static android.system.OsConstants.RT_SCOPE_LINK; 25fd31b9d46ea09dc7d74ddc03ab7e5ecfbe80b3dcHugo Benichiimport static android.system.OsConstants.RT_SCOPE_SITE; 26fd31b9d46ea09dc7d74ddc03ab7e5ecfbe80b3dcHugo Benichiimport static android.system.OsConstants.RT_SCOPE_UNIVERSE; 27fd31b9d46ea09dc7d74ddc03ab7e5ecfbe80b3dcHugo Benichi 28ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport android.os.Parcel; 29ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport android.os.Parcelable; 308c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colittiimport android.util.Pair; 31ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 32b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwaltimport java.net.Inet4Address; 33befe778c73e48417942fc31c06509bac8e5ca0d2Erik Klineimport java.net.Inet6Address; 34ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport java.net.InetAddress; 35ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport java.net.InterfaceAddress; 36ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriffimport java.net.UnknownHostException; 37ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 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 */ 791dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi private 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() { 1041dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi if (isIPv6()) { 105befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline byte[] bytes = address.getAddress(); 1061eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline return ((bytes[0] & (byte)0xfe) == (byte)0xfc); 107befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline } 108befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline return false; 109befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline } 110befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline 111befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline /** 1121dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi * @return true if the address is IPv6. 1131dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi * @hide 1141dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi */ 1151dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi public boolean isIPv6() { 1161dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi return address instanceof Inet6Address; 1171dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi } 1181dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi 1191dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi /** 1201dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi * @return true if the address is IPv4 or is a mapped IPv4 address. 1211dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi * @hide 1221dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi */ 1231dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi public boolean isIPv4() { 1241dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi return address instanceof Inet4Address; 1251dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi } 1261dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi 1271dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi /** 12864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Utility function for the constructors. 12964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 13064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti private void init(InetAddress address, int prefixLength, int flags, int scope) { 13164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti if (address == null || 13264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti address.isMulticastAddress() || 13364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti prefixLength < 0 || 1341dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi (address instanceof Inet4Address && prefixLength > 32) || 135b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt (prefixLength > 128)) { 136b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt throw new IllegalArgumentException("Bad LinkAddress params " + address + 1376eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti "/" + prefixLength); 138b979f79158f9c470fa09ff3b96d72db274262201Robert Greenwalt } 139ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff this.address = address; 14096ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff this.prefixLength = prefixLength; 14164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.flags = flags; 14264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.scope = scope; 14364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 14464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 14564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 14664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with 14764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * the specified flags and scope. Flags and scope are not checked for validity. 14864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param address The IP address. 14964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param prefixLength The prefix length. 150fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address. 151fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @param scope An integer defining the scope in which the address is unique (e.g., 152fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}). 153fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 15464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 15564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public LinkAddress(InetAddress address, int prefixLength, int flags, int scope) { 15664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti init(address, prefixLength, flags, scope); 157ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 158ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 159e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti /** 160e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length. 16164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * The flags are set to zero and the scope is determined from the address. 162e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * @param address The IP address. 163e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * @param prefixLength The prefix length. 164fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 165e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti */ 1666eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti public LinkAddress(InetAddress address, int prefixLength) { 16764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this(address, prefixLength, 0, 0); 16864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.scope = scopeForUnicastAddress(address); 1696eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } 1706eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti 171e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti /** 172e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Constructs a new {@code LinkAddress} from an {@code InterfaceAddress}. 17364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * The flags are set to zero and the scope is determined from the address. 174e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * @param interfaceAddress The interface address. 175fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 176e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti */ 177ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public LinkAddress(InterfaceAddress interfaceAddress) { 17864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this(interfaceAddress.getAddress(), 1796eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti interfaceAddress.getNetworkPrefixLength()); 1806eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti } 1816eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti 1826eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti /** 1836eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or 18464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * "2001:db8::1/64". The flags are set to zero and the scope is determined from the address. 1856eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti * @param string The string to parse. 186fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 1876eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti */ 1886eb8a62a26f35ed1c2938945bb86a65f486a8052Lorenzo Colitti public LinkAddress(String address) { 18964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this(address, 0, 0); 19064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.scope = scopeForUnicastAddress(this.address); 19164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 19264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 19364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 19464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or 19564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * "2001:db8::1/64", with the specified flags and scope. 19664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param string The string to parse. 19764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param flags The address flags. 19864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param scope The address scope. 199fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 20064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 20164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public LinkAddress(String address, int flags, int scope) { 2028c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti // This may throw an IllegalArgumentException; catching it is the caller's responsibility. 2031dfb6b67555d04973dfb9d1100dfc1c6a5200633Hugo Benichi // TODO: consider rejecting mapped IPv4 addresses such as "::ffff:192.0.2.5/24". 2048c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti Pair<InetAddress, Integer> ipAndMask = NetworkUtils.parseIpAndMask(address); 2058c6c2c3c929acad783b9a56b8d9efa597d0ae609Lorenzo Colitti init(ipAndMask.first, ipAndMask.second, flags, scope); 206ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 207ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 20864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 20964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Returns a string representation of this address, such as "192.0.2.1/24" or "2001:db8::1/64". 21064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * The string representation does not contain the flags and scope, just the address and prefix 21164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * length. 21264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 213ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff @Override 214ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public String toString() { 215e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti return address.getHostAddress() + "/" + prefixLength; 216ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 217ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 218ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 21964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Compares this {@code LinkAddress} instance against {@code obj}. Two addresses are equal if 2207dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * their address, prefix length, flags and scope are equal. Thus, for example, two addresses 2217dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * that have the same address and prefix length are not equal if one of them is deprecated and 2227dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * the other is not. 223ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * 224ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @param obj the object to be tested for equality. 225ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * @return {@code true} if both objects are equal, {@code false} otherwise. 226ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 227ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff @Override 228ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public boolean equals(Object obj) { 229ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff if (!(obj instanceof LinkAddress)) { 230ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return false; 231ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 232ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff LinkAddress linkAddress = (LinkAddress) obj; 233ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return this.address.equals(linkAddress.address) && 23464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.prefixLength == linkAddress.prefixLength && 23564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.flags == linkAddress.flags && 23664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti this.scope == linkAddress.scope; 237ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 238ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 239e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti /** 240e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Returns a hashcode for this address. 2414e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang */ 242e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti @Override 2434e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang public int hashCode() { 24464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return address.hashCode() + 11 * prefixLength + 19 * flags + 43 * scope; 24564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 24664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 24764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 248fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Determines whether this {@code LinkAddress} and the provided {@code LinkAddress} 249fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * represent the same address. Two {@code LinkAddresses} represent the same address 250fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * if they have the same IP address and prefix length, even if their properties are 251fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * different. 25264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * 25364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @param other the {@code LinkAddress} to compare to. 25464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * @return {@code true} if both objects have the same address and prefix length, {@code false} 25564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * otherwise. 2567dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * @hide 25764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 25864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public boolean isSameAddressAs(LinkAddress other) { 25964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return address.equals(other.address) && prefixLength == other.prefixLength; 2604e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang } 2614e900091c4da26eb1c9f0d232ee0e50f4522cc69John Wang 262ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 263fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Returns the {@link InetAddress} of this {@code LinkAddress}. 264ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 265ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public InetAddress getAddress() { 266ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return address; 267ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 268ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 269ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 270fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Returns the prefix length of this {@code LinkAddress}. 271ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 2727dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti public int getPrefixLength() { 27396ca91761e6857c1ca2e4fafe5b35e4b5fefe5a1Irfan Sheriff return prefixLength; 274ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 275ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 276ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 2777dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * Returns the prefix length of this {@code LinkAddress}. 2787dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * TODO: Delete all callers and remove in favour of getPrefixLength(). 2797dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti * @hide 2807dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti */ 2817dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti public int getNetworkPrefixLength() { 2827dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti return getPrefixLength(); 2837dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti } 2847dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti 2857dc78cf3af9fd11a4f1e2e981ce584a23755ea9eLorenzo Colitti /** 286fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Returns the flags of this {@code LinkAddress}. 28764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 28864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public int getFlags() { 28964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return flags; 29064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 29164483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 29264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 293fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * Returns the scope of this {@code LinkAddress}. 29464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 29564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public int getScope() { 29664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return scope; 29764483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 29864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 29964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 30064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti * Returns true if this {@code LinkAddress} is global scope and preferred. 301fd202e6f84ab0ee6a64aa81f94c3039eb10f8e17Robert Greenwalt * @hide 30264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti */ 30364483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti public boolean isGlobalPreferred() { 304befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline /** 305befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * Note that addresses flagged as IFA_F_OPTIMISTIC are 306befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * simultaneously flagged as IFA_F_TENTATIVE (when the tentative 307befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * state has cleared either DAD has succeeded or failed, and both 308befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline * flags are cleared regardless). 309befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline */ 31064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return (scope == RT_SCOPE_UNIVERSE && 311befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline !isIPv6ULA() && 312befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L && 313befe778c73e48417942fc31c06509bac8e5ca0d2Erik Kline ((flags & IFA_F_TENTATIVE) == 0L || (flags & IFA_F_OPTIMISTIC) != 0L)); 31464483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti } 31564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti 31664483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti /** 317e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti * Implement the Parcelable interface. 318ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 319ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public int describeContents() { 320ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return 0; 321ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 322ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 323ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 324ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Implement the Parcelable interface. 325ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 326ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public void writeToParcel(Parcel dest, int flags) { 327e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti dest.writeByteArray(address.getAddress()); 328e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti dest.writeInt(prefixLength); 32964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti dest.writeInt(this.flags); 33064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti dest.writeInt(scope); 331ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 332ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 333ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff /** 334ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff * Implement the Parcelable interface. 335ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff */ 336ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public static final Creator<LinkAddress> CREATOR = 337ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff new Creator<LinkAddress>() { 338ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public LinkAddress createFromParcel(Parcel in) { 339ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff InetAddress address = null; 340e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti try { 341e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti address = InetAddress.getByAddress(in.createByteArray()); 342e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti } catch (UnknownHostException e) { 343e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti // Nothing we can do here. When we call the constructor, we'll throw an 344e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti // IllegalArgumentException, because a LinkAddress can't have a null 345e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti // InetAddress. 346ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 347e1ad1849f3a65c1ff06919351ef1d73e9bc8854eLorenzo Colitti int prefixLength = in.readInt(); 34864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti int flags = in.readInt(); 34964483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti int scope = in.readInt(); 35064483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti return new LinkAddress(address, prefixLength, flags, scope); 351ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 352ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff 353ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff public LinkAddress[] newArray(int size) { 354ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff return new LinkAddress[size]; 355ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff } 356ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff }; 357ed5d7d17c9e9837ce7a6a10698cce9f6e4101acdIrfan Sheriff} 358