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