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.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 
     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
     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      */
     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      */
    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 
    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 
    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         }
    190         dest.writeString(domains);
    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         s.domains = in.readString();
    202     }
    203 }
    204