StaticIpConfiguration.java revision 2dfb79a54adeb4bcf1f62332a9db467fce302ced
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