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