blob: 58b1b88d897608d547c67dd95fc8d3c0e7862e3c [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
19import android.net.LinkAddress;
20import android.os.Parcelable;
21import android.os.Parcel;
22
23import java.net.InetAddress;
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090024import java.util.ArrayList;
25import java.util.List;
26import 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 */
48public class StaticIpConfiguration implements Parcelable {
49 public LinkAddress ipAddress;
50 public InetAddress gateway;
51 public final ArrayList<InetAddress> dnsServers;
52 public String domains;
53
54 public StaticIpConfiguration() {
55 dnsServers = new ArrayList<InetAddress>();
56 }
57
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
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
Lorenzo Colitti8316b8192015-01-20 15:53:02 +090078 * 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.
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090082 */
83 public List<RouteInfo> getRoutes(String iface) {
Lorenzo Colitti8316b8192015-01-20 15:53:02 +090084 List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090085 if (ipAddress != null) {
Lorenzo Colitti8316b8192015-01-20 15:53:02 +090086 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 }
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090091 }
92 if (gateway != null) {
Lorenzo Colitti8316b8192015-01-20 15:53:02 +090093 routes.add(new RouteInfo((IpPrefix) null, gateway, iface));
Lorenzo Colitti0a82e802014-07-31 00:48:01 +090094 }
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 */
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 }
Paul Jensenb3b70972014-11-05 09:35:26 -0500116 lp.setDomains(domains);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900117 return lp;
118 }
119
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
Erik Klineacda32c2016-05-13 17:50:25 +0900134 str.append(" ] Domains ");
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900135 if (domains != null) str.append(domains);
136 return str.toString();
137 }
138
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
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 */
178 public int describeContents() {
179 return 0;
180 }
181
182 /** Implement the Parcelable interface */
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 }
Lorenzo Colittid0cc5442015-01-29 17:10:52 +0900190 dest.writeString(domains);
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900191 }
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 }
Lorenzo Colittid0cc5442015-01-29 17:10:52 +0900201 s.domains = in.readString();
Lorenzo Colitti0a82e802014-07-31 00:48:01 +0900202 }
203}