StaticIpConfiguration.java revision 2dfb79a54adeb4bcf1f62332a9db467fce302ced
1a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek/*
2a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek * Copyright (C) 2014 The Android Open Source Project
3a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek *
4a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek * Licensed under the Apache License, Version 2.0 (the "License");
5a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek * you may not use this file except in compliance with the License.
6a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek * You may obtain a copy of the License at
7a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek *
8a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek *      http://www.apache.org/licenses/LICENSE-2.0
9a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek *
10a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek * Unless required by applicable law or agreed to in writing, software
11a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek * distributed under the License is distributed on an "AS IS" BASIS,
12a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek * See the License for the specific language governing permissions and
14a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek * limitations under the License.
1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth */
16a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
17a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenekpackage android.net;
1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth
1948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenekimport android.net.LinkAddress;
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruthimport android.os.Parcelable;
21a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenekimport android.os.Parcel;
22a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
23a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenekimport java.net.InetAddress;
240a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenekimport java.net.UnknownHostException;
250a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenekimport java.util.ArrayList;
260a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenekimport java.util.List;
27a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenekimport java.util.Objects;
28cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
29cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek/**
30cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * Class that describes static IP configuration.
31cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek *
32cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * This class is different from LinkProperties because it represents
33cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * configuration intent. The general contract is that if we can represent
34cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * a configuration here, then we should be able to configure it on a network.
35cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * The intent is that it closely match the UI we have for configuring networks.
36cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek *
37cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * In contrast, LinkProperties represents current state. It is much more
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * expressive. For example, it supports multiple IP addresses, multiple routes,
39cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * stacked interfaces, and so on. Because LinkProperties is so expressive,
40cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * using it to represent configuration intent as well as current state causes
41cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * problems. For example, we could unknowingly save a configuration that we are
42cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * not in fact capable of applying, or we could save a configuration that the
43cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek * UI cannot display, which has the potential for malicious code to hide
44016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek * hostile or unexpected configuration from the user: see, for example,
45016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek * http://b/12663469 and http://b/16893413 .
46016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek *
47016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek * @hide
48016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek */
49b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenekpublic class StaticIpConfiguration implements Parcelable {
50b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek    public LinkAddress ipAddress;
51b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek    public InetAddress gateway;
5248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    public final ArrayList<InetAddress> dnsServers;
5348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    public String domains;
5448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
5548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    public StaticIpConfiguration() {
5648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        dnsServers = new ArrayList<InetAddress>();
5748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    }
5848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
59a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek    public StaticIpConfiguration(StaticIpConfiguration source) {
60016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        this();
61016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        if (source != null) {
620b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek            // All of these except dnsServers are immutable, so no need to make copies.
630b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek            ipAddress = source.ipAddress;
640b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek            gateway = source.gateway;
65a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek            dnsServers.addAll(source.dnsServers);
665dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek            domains = source.domains;
67a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek        }
6848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    }
6948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
7048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    public void clear() {
719ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek        ipAddress = null;
729ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek        gateway = null;
739ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek        dnsServers.clear();
7448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        domains = null;
7548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    }
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /**
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines     * Returns the network routes specified by this object. Will typically include a
7948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek     * directly-connected route for the IP address's local subnet and a default route. If the
8048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek     * default gateway is not covered by the directly-connected route, it will also contain a host
8148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek     * route to the gateway as well. This configuration is arguably invalid, but it used to work
8248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek     * in K and earlier, and other OSes appear to accept it.
83016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek     */
84016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek    public List<RouteInfo> getRoutes(String iface) {
85016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
86016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        if (ipAddress != null) {
87016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek            RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface);
88b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek            routes.add(connectedRoute);
89b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek            if (gateway != null && !connectedRoute.matches(gateway)) {
90b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek                routes.add(RouteInfo.makeHostRoute(gateway, iface));
91b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek            }
92be9af1288881110e406b87914162eaa59f1e5918Lang Hames        }
93b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek        if (gateway != null) {
94b80e5bb7c7c47e06f2ff9c2f9d4b6b138db180e2Ted Kremenek            routes.add(new RouteInfo((IpPrefix) null, gateway, iface));
9548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        }
9648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        return routes;
9748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    }
9848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
9948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    /**
10048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek     * Returns a LinkProperties object expressing the data in this object. Note that the information
10148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek     * contained in the LinkProperties will not be a complete picture of the link's configuration,
10248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek     * because any configuration information that is obtained dynamically by the network (e.g.,
10348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek     * IPv6 configuration) will not be included.
10448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek     */
10548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    public LinkProperties toLinkProperties(String iface) {
10648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        LinkProperties lp = new LinkProperties();
10748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        lp.setInterfaceName(iface);
108d36aa359e2f45cd22c7366a015ad94de08044dbbNico Weber        if (ipAddress != null) {
10948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek            lp.addLinkAddress(ipAddress);
11048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        }
111016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        for (RouteInfo route : getRoutes(iface)) {
112016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek            lp.addRoute(route);
113016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        }
114016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        for (InetAddress dns : dnsServers) {
115016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek            lp.addDnsServer(dns);
116016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        }
117016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        lp.setDomains(domains);
118016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        return lp;
119016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek    }
120016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek
121016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek    public String toString() {
122016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek        StringBuffer str = new StringBuffer();
123016c33d7bbca20c096ad8c7400b70f33aadfb224Ted Kremenek
1240b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek        str.append("IP address ");
1250b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek        if (ipAddress != null ) str.append(ipAddress).append(" ");
1260b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek
1270b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek        str.append("Gateway ");
1280b5c5e487bbbdeb2a7688e6c753d3b2a7c337604Ted Kremenek        if (gateway != null) str.append(gateway.getHostAddress()).append(" ");
1299ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek
1309ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek        str.append(" DNS servers: [");
1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        for (InetAddress dnsServer : dnsServers) {
1329ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek            str.append(" ").append(dnsServer.getHostAddress());
1339ba05cd2e24e600ab59b2ed893ae598abbbc9a36Ted Kremenek        }
1345dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek
1355dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek        str.append(" ] Domains");
1365dbd990d7978fb990b61a9bcf1b71314a3e743feTed Kremenek        if (domains != null) str.append(domains);
1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        return str.toString();
138a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek    }
1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
140a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek    public int hashCode() {
141a6d62a10a6e1b8aa3c8294d8cac842c3720df7ffTed Kremenek        int result = 13;
14248fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode());
14348fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        result = 47 * result + (gateway == null ? 0 : gateway.hashCode());
1446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        result = 47 * result + (domains == null ? 0 : domains.hashCode());
14548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        result = 47 * result + dnsServers.hashCode();
14648fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        return result;
14748fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    }
14848fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek
14948fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    @Override
15048fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    public boolean equals(Object obj) {
15148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek        if (this == obj) return true;
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (!(obj instanceof StaticIpConfiguration)) return false;
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        StaticIpConfiguration other = (StaticIpConfiguration) obj;
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        return other != null &&
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                Objects.equals(ipAddress, other.ipAddress) &&
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                Objects.equals(gateway, other.gateway) &&
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                dnsServers.equals(other.dnsServers) &&
16148fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek                Objects.equals(domains, other.domains);
1626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
1636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
16448fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    /** Implement the Parcelable interface */
16548fa1361505c51cdc5e78deffdbdd7c334cca5d0Ted Kremenek    public static Creator<StaticIpConfiguration> CREATOR =
1660a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek        new Creator<StaticIpConfiguration>() {
1670a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek            public StaticIpConfiguration createFromParcel(Parcel in) {
1680a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek                StaticIpConfiguration s = new StaticIpConfiguration();
1690a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek                readFromParcel(s, in);
1700a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek                return s;
1710a4c0988c237678f4b5ba7375e51d24d2c55d67fTed Kremenek            }
172cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
173cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek            public StaticIpConfiguration[] newArray(int size) {
174cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek                return new StaticIpConfiguration[size];
175cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek            }
1766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        };
177cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
178cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek    /** Implement the Parcelable interface */
179cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek    public int describeContents() {
180cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        return 0;
181cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek    }
182cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek
1836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    /** Implement the Parcelable interface */
184cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek    public void writeToParcel(Parcel dest, int flags) {
185cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        dest.writeParcelable(ipAddress, flags);
1866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        NetworkUtils.parcelInetAddress(dest, gateway, flags);
1876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        dest.writeInt(dnsServers.size());
188cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        for (InetAddress dnsServer : dnsServers) {
189cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek            NetworkUtils.parcelInetAddress(dest, dnsServer, flags);
190cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        }
191cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek    }
1926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    protected static void readFromParcel(StaticIpConfiguration s, Parcel in) {
194cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        s.ipAddress = in.readParcelable(null);
195cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        s.gateway = NetworkUtils.unparcelInetAddress(in);
196cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        s.dnsServers.clear();
197cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        int size = in.readInt();
198cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        for (int i = 0; i < size; i++) {
199cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek            s.dnsServers.add(NetworkUtils.unparcelInetAddress(in));
200cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek        }
201cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek    }
202cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek}
203cc85d217d329aa3c78aa3f57a238e5b7931ee2c5Ted Kremenek