1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.net; 18 19import android.net.LinkAddress; 20import android.os.Parcelable; 21import android.os.Parcel; 22 23import java.net.InetAddress; 24import java.net.UnknownHostException; 25import java.util.ArrayList; 26import java.util.List; 27import java.util.Objects; 28 29/** 30 * Class that describes static IP configuration. 31 * 32 * This class is different from LinkProperties because it represents 33 * configuration intent. The general contract is that if we can represent 34 * a configuration here, then we should be able to configure it on a network. 35 * The intent is that it closely match the UI we have for configuring networks. 36 * 37 * In contrast, LinkProperties represents current state. It is much more 38 * expressive. For example, it supports multiple IP addresses, multiple routes, 39 * stacked interfaces, and so on. Because LinkProperties is so expressive, 40 * using it to represent configuration intent as well as current state causes 41 * problems. For example, we could unknowingly save a configuration that we are 42 * not in fact capable of applying, or we could save a configuration that the 43 * UI cannot display, which has the potential for malicious code to hide 44 * hostile or unexpected configuration from the user: see, for example, 45 * http://b/12663469 and http://b/16893413 . 46 * 47 * @hide 48 */ 49public class StaticIpConfiguration implements Parcelable { 50 public LinkAddress ipAddress; 51 public InetAddress gateway; 52 public final ArrayList<InetAddress> dnsServers; 53 public String domains; 54 55 public StaticIpConfiguration() { 56 dnsServers = new ArrayList<InetAddress>(); 57 } 58 59 public StaticIpConfiguration(StaticIpConfiguration source) { 60 this(); 61 if (source != null) { 62 // All of these except dnsServers are immutable, so no need to make copies. 63 ipAddress = source.ipAddress; 64 gateway = source.gateway; 65 dnsServers.addAll(source.dnsServers); 66 domains = source.domains; 67 } 68 } 69 70 public void clear() { 71 ipAddress = null; 72 gateway = null; 73 dnsServers.clear(); 74 domains = null; 75 } 76 77 /** 78 * Returns the network routes specified by this object. Will typically include a 79 * directly-connected route for the IP address's local subnet and a default route. If the 80 * default gateway is not covered by the directly-connected route, it will also contain a host 81 * route to the gateway as well. This configuration is arguably invalid, but it used to work 82 * in K and earlier, and other OSes appear to accept it. 83 */ 84 public List<RouteInfo> getRoutes(String iface) { 85 List<RouteInfo> routes = new ArrayList<RouteInfo>(3); 86 if (ipAddress != null) { 87 RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface); 88 routes.add(connectedRoute); 89 if (gateway != null && !connectedRoute.matches(gateway)) { 90 routes.add(RouteInfo.makeHostRoute(gateway, iface)); 91 } 92 } 93 if (gateway != null) { 94 routes.add(new RouteInfo((IpPrefix) null, gateway, iface)); 95 } 96 return routes; 97 } 98 99 /** 100 * Returns a LinkProperties object expressing the data in this object. Note that the information 101 * contained in the LinkProperties will not be a complete picture of the link's configuration, 102 * because any configuration information that is obtained dynamically by the network (e.g., 103 * IPv6 configuration) will not be included. 104 */ 105 public LinkProperties toLinkProperties(String iface) { 106 LinkProperties lp = new LinkProperties(); 107 lp.setInterfaceName(iface); 108 if (ipAddress != null) { 109 lp.addLinkAddress(ipAddress); 110 } 111 for (RouteInfo route : getRoutes(iface)) { 112 lp.addRoute(route); 113 } 114 for (InetAddress dns : dnsServers) { 115 lp.addDnsServer(dns); 116 } 117 lp.setDomains(domains); 118 return lp; 119 } 120 121 public String toString() { 122 StringBuffer str = new StringBuffer(); 123 124 str.append("IP address "); 125 if (ipAddress != null ) str.append(ipAddress).append(" "); 126 127 str.append("Gateway "); 128 if (gateway != null) str.append(gateway.getHostAddress()).append(" "); 129 130 str.append(" DNS servers: ["); 131 for (InetAddress dnsServer : dnsServers) { 132 str.append(" ").append(dnsServer.getHostAddress()); 133 } 134 135 str.append(" ] Domains"); 136 if (domains != null) str.append(domains); 137 return str.toString(); 138 } 139 140 public int hashCode() { 141 int result = 13; 142 result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode()); 143 result = 47 * result + (gateway == null ? 0 : gateway.hashCode()); 144 result = 47 * result + (domains == null ? 0 : domains.hashCode()); 145 result = 47 * result + dnsServers.hashCode(); 146 return result; 147 } 148 149 @Override 150 public boolean equals(Object obj) { 151 if (this == obj) return true; 152 153 if (!(obj instanceof StaticIpConfiguration)) return false; 154 155 StaticIpConfiguration other = (StaticIpConfiguration) obj; 156 157 return other != null && 158 Objects.equals(ipAddress, other.ipAddress) && 159 Objects.equals(gateway, other.gateway) && 160 dnsServers.equals(other.dnsServers) && 161 Objects.equals(domains, other.domains); 162 } 163 164 /** Implement the Parcelable interface */ 165 public static Creator<StaticIpConfiguration> CREATOR = 166 new Creator<StaticIpConfiguration>() { 167 public StaticIpConfiguration createFromParcel(Parcel in) { 168 StaticIpConfiguration s = new StaticIpConfiguration(); 169 readFromParcel(s, in); 170 return s; 171 } 172 173 public StaticIpConfiguration[] newArray(int size) { 174 return new StaticIpConfiguration[size]; 175 } 176 }; 177 178 /** Implement the Parcelable interface */ 179 public int describeContents() { 180 return 0; 181 } 182 183 /** Implement the Parcelable interface */ 184 public void writeToParcel(Parcel dest, int flags) { 185 dest.writeParcelable(ipAddress, flags); 186 NetworkUtils.parcelInetAddress(dest, gateway, flags); 187 dest.writeInt(dnsServers.size()); 188 for (InetAddress dnsServer : dnsServers) { 189 NetworkUtils.parcelInetAddress(dest, dnsServer, flags); 190 } 191 } 192 193 protected static void readFromParcel(StaticIpConfiguration s, Parcel in) { 194 s.ipAddress = in.readParcelable(null); 195 s.gateway = NetworkUtils.unparcelInetAddress(in); 196 s.dnsServers.clear(); 197 int size = in.readInt(); 198 for (int i = 0; i < size; i++) { 199 s.dnsServers.add(NetworkUtils.unparcelInetAddress(in)); 200 } 201 } 202} 203