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