10a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti/* 20a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * Copyright (C) 2014 The Android Open Source Project 30a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * 40a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License"); 50a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * you may not use this file except in compliance with the License. 60a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * You may obtain a copy of the License at 70a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * 80a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * http://www.apache.org/licenses/LICENSE-2.0 90a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * 100a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * Unless required by applicable law or agreed to in writing, software 110a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS, 120a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * See the License for the specific language governing permissions and 140a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * limitations under the License. 150a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti */ 160a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 170a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittipackage android.net; 180a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 190a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittiimport android.net.LinkAddress; 200a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittiimport android.os.Parcelable; 210a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittiimport android.os.Parcel; 220a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 230a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittiimport java.net.InetAddress; 240a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittiimport java.util.ArrayList; 250a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittiimport java.util.List; 260a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittiimport java.util.Objects; 270a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 280a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti/** 290a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * Class that describes static IP configuration. 300a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * 310a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * This class is different from LinkProperties because it represents 320a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * configuration intent. The general contract is that if we can represent 330a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * a configuration here, then we should be able to configure it on a network. 340a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * The intent is that it closely match the UI we have for configuring networks. 350a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * 360a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * In contrast, LinkProperties represents current state. It is much more 370a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * expressive. For example, it supports multiple IP addresses, multiple routes, 380a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * stacked interfaces, and so on. Because LinkProperties is so expressive, 390a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * using it to represent configuration intent as well as current state causes 400a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * problems. For example, we could unknowingly save a configuration that we are 410a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * not in fact capable of applying, or we could save a configuration that the 420a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * UI cannot display, which has the potential for malicious code to hide 430a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * hostile or unexpected configuration from the user: see, for example, 440a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * http://b/12663469 and http://b/16893413 . 450a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * 460a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * @hide 470a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti */ 480a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colittipublic class StaticIpConfiguration implements Parcelable { 490a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public LinkAddress ipAddress; 500a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public InetAddress gateway; 510a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public final ArrayList<InetAddress> dnsServers; 520a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public String domains; 530a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 540a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public StaticIpConfiguration() { 550a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti dnsServers = new ArrayList<InetAddress>(); 560a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 570a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 580a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public StaticIpConfiguration(StaticIpConfiguration source) { 590a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti this(); 600a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti if (source != null) { 610a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti // All of these except dnsServers are immutable, so no need to make copies. 620a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti ipAddress = source.ipAddress; 630a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti gateway = source.gateway; 640a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti dnsServers.addAll(source.dnsServers); 650a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti domains = source.domains; 660a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 670a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 680a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 690a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public void clear() { 700a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti ipAddress = null; 710a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti gateway = null; 720a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti dnsServers.clear(); 730a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti domains = null; 740a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 750a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 760a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti /** 770a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * Returns the network routes specified by this object. Will typically include a 788316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti * directly-connected route for the IP address's local subnet and a default route. If the 798316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti * default gateway is not covered by the directly-connected route, it will also contain a host 808316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti * route to the gateway as well. This configuration is arguably invalid, but it used to work 818316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti * in K and earlier, and other OSes appear to accept it. 820a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti */ 830a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public List<RouteInfo> getRoutes(String iface) { 848316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti List<RouteInfo> routes = new ArrayList<RouteInfo>(3); 850a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti if (ipAddress != null) { 868316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface); 878316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti routes.add(connectedRoute); 888316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti if (gateway != null && !connectedRoute.matches(gateway)) { 898316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti routes.add(RouteInfo.makeHostRoute(gateway, iface)); 908316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti } 910a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 920a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti if (gateway != null) { 938316b819b2837b6ad25957328ba7b2fdaf705fa9Lorenzo Colitti routes.add(new RouteInfo((IpPrefix) null, gateway, iface)); 940a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 950a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti return routes; 960a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 970a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 980a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti /** 990a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * Returns a LinkProperties object expressing the data in this object. Note that the information 1000a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * contained in the LinkProperties will not be a complete picture of the link's configuration, 1010a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * because any configuration information that is obtained dynamically by the network (e.g., 1020a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti * IPv6 configuration) will not be included. 1030a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti */ 1040a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public LinkProperties toLinkProperties(String iface) { 1050a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti LinkProperties lp = new LinkProperties(); 1060a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti lp.setInterfaceName(iface); 1070a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti if (ipAddress != null) { 1080a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti lp.addLinkAddress(ipAddress); 1090a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1100a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti for (RouteInfo route : getRoutes(iface)) { 1110a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti lp.addRoute(route); 1120a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1130a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti for (InetAddress dns : dnsServers) { 1140a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti lp.addDnsServer(dns); 1150a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 116b3b70975d9b1d9969dc58ed880baa13509a8933dPaul Jensen lp.setDomains(domains); 1170a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti return lp; 1180a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1190a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1200a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public String toString() { 1210a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti StringBuffer str = new StringBuffer(); 1220a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1230a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti str.append("IP address "); 1240a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti if (ipAddress != null ) str.append(ipAddress).append(" "); 1250a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1260a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti str.append("Gateway "); 1270a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti if (gateway != null) str.append(gateway.getHostAddress()).append(" "); 1280a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1290a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti str.append(" DNS servers: ["); 1300a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti for (InetAddress dnsServer : dnsServers) { 1310a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti str.append(" ").append(dnsServer.getHostAddress()); 1320a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1330a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 134acda32c35fc6a30ce11abfddb26ec5052de063f4Erik Kline str.append(" ] Domains "); 1350a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti if (domains != null) str.append(domains); 1360a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti return str.toString(); 1370a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1380a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1390a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public int hashCode() { 1400a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti int result = 13; 1410a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode()); 1420a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti result = 47 * result + (gateway == null ? 0 : gateway.hashCode()); 1430a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti result = 47 * result + (domains == null ? 0 : domains.hashCode()); 1440a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti result = 47 * result + dnsServers.hashCode(); 1450a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti return result; 1460a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1470a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1480a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti @Override 1490a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public boolean equals(Object obj) { 1500a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti if (this == obj) return true; 1510a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1520a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti if (!(obj instanceof StaticIpConfiguration)) return false; 1530a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1540a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti StaticIpConfiguration other = (StaticIpConfiguration) obj; 1550a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1560a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti return other != null && 1570a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti Objects.equals(ipAddress, other.ipAddress) && 1580a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti Objects.equals(gateway, other.gateway) && 1590a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti dnsServers.equals(other.dnsServers) && 1600a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti Objects.equals(domains, other.domains); 1610a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1620a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1630a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti /** Implement the Parcelable interface */ 1640a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public static Creator<StaticIpConfiguration> CREATOR = 1650a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti new Creator<StaticIpConfiguration>() { 1660a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public StaticIpConfiguration createFromParcel(Parcel in) { 1670a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti StaticIpConfiguration s = new StaticIpConfiguration(); 1680a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti readFromParcel(s, in); 1690a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti return s; 1700a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1710a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1720a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public StaticIpConfiguration[] newArray(int size) { 1730a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti return new StaticIpConfiguration[size]; 1740a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1750a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti }; 1760a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1770a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti /** Implement the Parcelable interface */ 1780a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public int describeContents() { 1790a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti return 0; 1800a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1810a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1820a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti /** Implement the Parcelable interface */ 1830a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti public void writeToParcel(Parcel dest, int flags) { 1840a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti dest.writeParcelable(ipAddress, flags); 1850a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti NetworkUtils.parcelInetAddress(dest, gateway, flags); 1860a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti dest.writeInt(dnsServers.size()); 1870a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti for (InetAddress dnsServer : dnsServers) { 1880a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti NetworkUtils.parcelInetAddress(dest, dnsServer, flags); 1890a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 190d0cc544039ee7d35d0f1aa9fc9d0f57ef6dfbfb9Lorenzo Colitti dest.writeString(domains); 1910a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 1920a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti 1930a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti protected static void readFromParcel(StaticIpConfiguration s, Parcel in) { 1940a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti s.ipAddress = in.readParcelable(null); 1950a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti s.gateway = NetworkUtils.unparcelInetAddress(in); 1960a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti s.dnsServers.clear(); 1970a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti int size = in.readInt(); 1980a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti for (int i = 0; i < size; i++) { 1990a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti s.dnsServers.add(NetworkUtils.unparcelInetAddress(in)); 2000a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 201d0cc544039ee7d35d0f1aa9fc9d0f57ef6dfbfb9Lorenzo Colitti s.domains = in.readString(); 2020a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti } 2030a82e80073e193725a9d4c84a93db8a04b2456b9Lorenzo Colitti} 204