Home | History | Annotate | Download | only in net
      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.net.UnknownHostException;
     25 import java.util.ArrayList;
     26 import java.util.List;
     27 import 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  */
     49 public 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