blob: 8b264eeee3c9201b7507452e103b6c956ca24354 [file] [log] [blame]
Lorenzo Colitti0a82e802014-07-31 00:48:01 +09001/*
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
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +090019import android.annotation.SystemApi;
20import android.annotation.TestApi;
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010021import android.annotation.UnsupportedAppUsage;
Remi NGUYEN VAN231b52b2019-01-29 15:38:52 +090022import android.net.shared.InetAddressUtils;
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090023import android.os.Parcel;
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +090024import android.os.Parcelable;
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090025
26import java.net.InetAddress;
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090027import java.util.ArrayList;
28import java.util.List;
29import java.util.Objects;
30
31/**
32 * Class that describes static IP configuration.
33 *
34 * This class is different from LinkProperties because it represents
35 * configuration intent. The general contract is that if we can represent
36 * a configuration here, then we should be able to configure it on a network.
37 * The intent is that it closely match the UI we have for configuring networks.
38 *
39 * In contrast, LinkProperties represents current state. It is much more
40 * expressive. For example, it supports multiple IP addresses, multiple routes,
41 * stacked interfaces, and so on. Because LinkProperties is so expressive,
42 * using it to represent configuration intent as well as current state causes
43 * problems. For example, we could unknowingly save a configuration that we are
44 * not in fact capable of applying, or we could save a configuration that the
45 * UI cannot display, which has the potential for malicious code to hide
46 * hostile or unexpected configuration from the user: see, for example,
47 * http://b/12663469 and http://b/16893413 .
48 *
49 * @hide
50 */
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +090051@SystemApi
52@TestApi
53public final class StaticIpConfiguration implements Parcelable {
54 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010055 @UnsupportedAppUsage
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090056 public LinkAddress ipAddress;
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +090057 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010058 @UnsupportedAppUsage
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090059 public InetAddress gateway;
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +090060 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010061 @UnsupportedAppUsage
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090062 public final ArrayList<InetAddress> dnsServers;
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +090063 /** @hide */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +010064 @UnsupportedAppUsage
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090065 public String domains;
66
67 public StaticIpConfiguration() {
68 dnsServers = new ArrayList<InetAddress>();
69 }
70
71 public StaticIpConfiguration(StaticIpConfiguration source) {
72 this();
73 if (source != null) {
74 // All of these except dnsServers are immutable, so no need to make copies.
75 ipAddress = source.ipAddress;
76 gateway = source.gateway;
77 dnsServers.addAll(source.dnsServers);
78 domains = source.domains;
79 }
80 }
81
82 public void clear() {
83 ipAddress = null;
84 gateway = null;
85 dnsServers.clear();
86 domains = null;
87 }
88
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +090089 public LinkAddress getIpAddress() {
90 return ipAddress;
91 }
92
93 public void setIpAddress(LinkAddress ipAddress) {
94 this.ipAddress = ipAddress;
95 }
96
97 public InetAddress getGateway() {
98 return gateway;
99 }
100
101 public void setGateway(InetAddress gateway) {
102 this.gateway = gateway;
103 }
104
105 public List<InetAddress> getDnsServers() {
106 return dnsServers;
107 }
108
109 public String getDomains() {
110 return domains;
111 }
112
113 public void setDomains(String newDomains) {
114 domains = newDomains;
115 }
116
117 /**
118 * Add a DNS server to this configuration.
119 */
120 public void addDnsServer(InetAddress server) {
121 dnsServers.add(server);
122 }
123
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900124 /**
125 * Returns the network routes specified by this object. Will typically include a
Lorenzo Colitti8316b8192015-01-20 15:53:02 +0900126 * directly-connected route for the IP address's local subnet and a default route. If the
127 * default gateway is not covered by the directly-connected route, it will also contain a host
128 * route to the gateway as well. This configuration is arguably invalid, but it used to work
129 * in K and earlier, and other OSes appear to accept it.
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900130 */
131 public List<RouteInfo> getRoutes(String iface) {
Lorenzo Colitti8316b8192015-01-20 15:53:02 +0900132 List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900133 if (ipAddress != null) {
Lorenzo Colitti8316b8192015-01-20 15:53:02 +0900134 RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface);
135 routes.add(connectedRoute);
136 if (gateway != null && !connectedRoute.matches(gateway)) {
137 routes.add(RouteInfo.makeHostRoute(gateway, iface));
138 }
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900139 }
140 if (gateway != null) {
Lorenzo Colitti8316b8192015-01-20 15:53:02 +0900141 routes.add(new RouteInfo((IpPrefix) null, gateway, iface));
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900142 }
143 return routes;
144 }
145
146 /**
147 * Returns a LinkProperties object expressing the data in this object. Note that the information
148 * contained in the LinkProperties will not be a complete picture of the link's configuration,
149 * because any configuration information that is obtained dynamically by the network (e.g.,
150 * IPv6 configuration) will not be included.
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +0900151 * @hide
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900152 */
153 public LinkProperties toLinkProperties(String iface) {
154 LinkProperties lp = new LinkProperties();
155 lp.setInterfaceName(iface);
156 if (ipAddress != null) {
157 lp.addLinkAddress(ipAddress);
158 }
159 for (RouteInfo route : getRoutes(iface)) {
160 lp.addRoute(route);
161 }
162 for (InetAddress dns : dnsServers) {
163 lp.addDnsServer(dns);
164 }
Paul Jensenb3b70972014-11-05 09:35:26 -0500165 lp.setDomains(domains);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900166 return lp;
167 }
168
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +0900169 @Override
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900170 public String toString() {
171 StringBuffer str = new StringBuffer();
172
173 str.append("IP address ");
174 if (ipAddress != null ) str.append(ipAddress).append(" ");
175
176 str.append("Gateway ");
177 if (gateway != null) str.append(gateway.getHostAddress()).append(" ");
178
179 str.append(" DNS servers: [");
180 for (InetAddress dnsServer : dnsServers) {
181 str.append(" ").append(dnsServer.getHostAddress());
182 }
183
Erik Klineacda32c2016-05-13 17:50:25 +0900184 str.append(" ] Domains ");
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900185 if (domains != null) str.append(domains);
186 return str.toString();
187 }
188
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +0900189 @Override
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900190 public int hashCode() {
191 int result = 13;
192 result = 47 * result + (ipAddress == null ? 0 : ipAddress.hashCode());
193 result = 47 * result + (gateway == null ? 0 : gateway.hashCode());
194 result = 47 * result + (domains == null ? 0 : domains.hashCode());
195 result = 47 * result + dnsServers.hashCode();
196 return result;
197 }
198
199 @Override
200 public boolean equals(Object obj) {
201 if (this == obj) return true;
202
203 if (!(obj instanceof StaticIpConfiguration)) return false;
204
205 StaticIpConfiguration other = (StaticIpConfiguration) obj;
206
207 return other != null &&
208 Objects.equals(ipAddress, other.ipAddress) &&
209 Objects.equals(gateway, other.gateway) &&
210 dnsServers.equals(other.dnsServers) &&
211 Objects.equals(domains, other.domains);
212 }
213
214 /** Implement the Parcelable interface */
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700215 public static final @android.annotation.NonNull Creator<StaticIpConfiguration> CREATOR =
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900216 new Creator<StaticIpConfiguration>() {
217 public StaticIpConfiguration createFromParcel(Parcel in) {
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +0900218 return readFromParcel(in);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900219 }
220
221 public StaticIpConfiguration[] newArray(int size) {
222 return new StaticIpConfiguration[size];
223 }
224 };
225
226 /** Implement the Parcelable interface */
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +0900227 @Override
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900228 public int describeContents() {
229 return 0;
230 }
231
232 /** Implement the Parcelable interface */
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +0900233 @Override
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900234 public void writeToParcel(Parcel dest, int flags) {
235 dest.writeParcelable(ipAddress, flags);
Remi NGUYEN VAN231b52b2019-01-29 15:38:52 +0900236 InetAddressUtils.parcelInetAddress(dest, gateway, flags);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900237 dest.writeInt(dnsServers.size());
238 for (InetAddress dnsServer : dnsServers) {
Remi NGUYEN VAN231b52b2019-01-29 15:38:52 +0900239 InetAddressUtils.parcelInetAddress(dest, dnsServer, flags);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900240 }
Lorenzo Colittid0cc5442015-01-29 17:10:52 +0900241 dest.writeString(domains);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900242 }
243
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +0900244 /** @hide */
245 public static StaticIpConfiguration readFromParcel(Parcel in) {
246 final StaticIpConfiguration s = new StaticIpConfiguration();
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900247 s.ipAddress = in.readParcelable(null);
Remi NGUYEN VAN231b52b2019-01-29 15:38:52 +0900248 s.gateway = InetAddressUtils.unparcelInetAddress(in);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900249 s.dnsServers.clear();
250 int size = in.readInt();
251 for (int i = 0; i < size; i++) {
Remi NGUYEN VAN231b52b2019-01-29 15:38:52 +0900252 s.dnsServers.add(InetAddressUtils.unparcelInetAddress(in));
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900253 }
Lorenzo Colittid0cc5442015-01-29 17:10:52 +0900254 s.domains = in.readString();
Remi NGUYEN VANa4bcc862019-01-28 13:28:35 +0900255 return s;
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900256 }
257}