1 /* 2 * Copyright (C) 2012 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.annotation.UnsupportedAppUsage; 20 import android.net.shared.InetAddressUtils; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.text.TextUtils; 24 import android.util.Log; 25 26 import java.net.Inet4Address; 27 import java.net.InetAddress; 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.Objects; 31 32 /** 33 * A simple object for retrieving the results of a DHCP request. 34 * Optimized (attempted) for that jni interface 35 * TODO: remove this class and replace with other existing constructs 36 * @hide 37 */ 38 public final class DhcpResults implements Parcelable { 39 private static final String TAG = "DhcpResults"; 40 41 @UnsupportedAppUsage 42 public LinkAddress ipAddress; 43 44 @UnsupportedAppUsage 45 public InetAddress gateway; 46 47 @UnsupportedAppUsage 48 public final ArrayList<InetAddress> dnsServers = new ArrayList<>(); 49 50 @UnsupportedAppUsage 51 public String domains; 52 53 @UnsupportedAppUsage 54 public Inet4Address serverAddress; 55 56 /** Vendor specific information (from RFC 2132). */ 57 @UnsupportedAppUsage 58 public String vendorInfo; 59 60 @UnsupportedAppUsage 61 public int leaseDuration; 62 63 /** Link MTU option. 0 means unset. */ 64 @UnsupportedAppUsage 65 public int mtu; 66 67 public String serverHostName; 68 DhcpResults()69 public DhcpResults() { 70 super(); 71 } 72 73 /** 74 * Create a {@link StaticIpConfiguration} based on the DhcpResults. 75 */ toStaticIpConfiguration()76 public StaticIpConfiguration toStaticIpConfiguration() { 77 return new StaticIpConfiguration.Builder() 78 .setIpAddress(ipAddress) 79 .setGateway(gateway) 80 .setDnsServers(dnsServers) 81 .setDomains(domains) 82 .build(); 83 } 84 DhcpResults(StaticIpConfiguration source)85 public DhcpResults(StaticIpConfiguration source) { 86 if (source != null) { 87 ipAddress = source.getIpAddress(); 88 gateway = source.getGateway(); 89 dnsServers.addAll(source.getDnsServers()); 90 domains = source.getDomains(); 91 } 92 } 93 94 /** copy constructor */ DhcpResults(DhcpResults source)95 public DhcpResults(DhcpResults source) { 96 this(source == null ? null : source.toStaticIpConfiguration()); 97 if (source != null) { 98 serverAddress = source.serverAddress; 99 vendorInfo = source.vendorInfo; 100 leaseDuration = source.leaseDuration; 101 mtu = source.mtu; 102 serverHostName = source.serverHostName; 103 } 104 } 105 106 /** 107 * @see StaticIpConfiguration#getRoutes(String) 108 * @hide 109 */ getRoutes(String iface)110 public List<RouteInfo> getRoutes(String iface) { 111 return toStaticIpConfiguration().getRoutes(iface); 112 } 113 114 /** 115 * Test if this DHCP lease includes vendor hint that network link is 116 * metered, and sensitive to heavy data transfers. 117 */ hasMeteredHint()118 public boolean hasMeteredHint() { 119 if (vendorInfo != null) { 120 return vendorInfo.contains("ANDROID_METERED"); 121 } else { 122 return false; 123 } 124 } 125 clear()126 public void clear() { 127 ipAddress = null; 128 gateway = null; 129 dnsServers.clear(); 130 domains = null; 131 serverAddress = null; 132 vendorInfo = null; 133 leaseDuration = 0; 134 mtu = 0; 135 serverHostName = null; 136 } 137 138 @Override toString()139 public String toString() { 140 StringBuffer str = new StringBuffer(super.toString()); 141 142 str.append(" DHCP server ").append(serverAddress); 143 str.append(" Vendor info ").append(vendorInfo); 144 str.append(" lease ").append(leaseDuration).append(" seconds"); 145 if (mtu != 0) str.append(" MTU ").append(mtu); 146 str.append(" Servername ").append(serverHostName); 147 148 return str.toString(); 149 } 150 151 @Override equals(Object obj)152 public boolean equals(Object obj) { 153 if (this == obj) return true; 154 155 if (!(obj instanceof DhcpResults)) return false; 156 157 DhcpResults target = (DhcpResults)obj; 158 159 return toStaticIpConfiguration().equals(target.toStaticIpConfiguration()) 160 && Objects.equals(serverAddress, target.serverAddress) 161 && Objects.equals(vendorInfo, target.vendorInfo) 162 && Objects.equals(serverHostName, target.serverHostName) 163 && leaseDuration == target.leaseDuration 164 && mtu == target.mtu; 165 } 166 167 /** 168 * Implement the Parcelable interface 169 */ 170 public static final @android.annotation.NonNull Creator<DhcpResults> CREATOR = 171 new Creator<DhcpResults>() { 172 public DhcpResults createFromParcel(Parcel in) { 173 return readFromParcel(in); 174 } 175 176 public DhcpResults[] newArray(int size) { 177 return new DhcpResults[size]; 178 } 179 }; 180 181 /** Implement the Parcelable interface */ writeToParcel(Parcel dest, int flags)182 public void writeToParcel(Parcel dest, int flags) { 183 toStaticIpConfiguration().writeToParcel(dest, flags); 184 dest.writeInt(leaseDuration); 185 dest.writeInt(mtu); 186 InetAddressUtils.parcelInetAddress(dest, serverAddress, flags); 187 dest.writeString(vendorInfo); 188 dest.writeString(serverHostName); 189 } 190 191 @Override describeContents()192 public int describeContents() { 193 return 0; 194 } 195 readFromParcel(Parcel in)196 private static DhcpResults readFromParcel(Parcel in) { 197 final StaticIpConfiguration s = StaticIpConfiguration.CREATOR.createFromParcel(in); 198 final DhcpResults dhcpResults = new DhcpResults(s); 199 dhcpResults.leaseDuration = in.readInt(); 200 dhcpResults.mtu = in.readInt(); 201 dhcpResults.serverAddress = (Inet4Address) InetAddressUtils.unparcelInetAddress(in); 202 dhcpResults.vendorInfo = in.readString(); 203 dhcpResults.serverHostName = in.readString(); 204 return dhcpResults; 205 } 206 207 // Utils for jni population - false on success 208 // Not part of the superclass because they're only used by the JNI iterface to the DHCP daemon. setIpAddress(String addrString, int prefixLength)209 public boolean setIpAddress(String addrString, int prefixLength) { 210 try { 211 Inet4Address addr = (Inet4Address) InetAddresses.parseNumericAddress(addrString); 212 ipAddress = new LinkAddress(addr, prefixLength); 213 } catch (IllegalArgumentException|ClassCastException e) { 214 Log.e(TAG, "setIpAddress failed with addrString " + addrString + "/" + prefixLength); 215 return true; 216 } 217 return false; 218 } 219 setGateway(String addrString)220 public boolean setGateway(String addrString) { 221 try { 222 gateway = InetAddresses.parseNumericAddress(addrString); 223 } catch (IllegalArgumentException e) { 224 Log.e(TAG, "setGateway failed with addrString " + addrString); 225 return true; 226 } 227 return false; 228 } 229 addDns(String addrString)230 public boolean addDns(String addrString) { 231 if (TextUtils.isEmpty(addrString) == false) { 232 try { 233 dnsServers.add(InetAddresses.parseNumericAddress(addrString)); 234 } catch (IllegalArgumentException e) { 235 Log.e(TAG, "addDns failed with addrString " + addrString); 236 return true; 237 } 238 } 239 return false; 240 } 241 getIpAddress()242 public LinkAddress getIpAddress() { 243 return ipAddress; 244 } 245 setIpAddress(LinkAddress ipAddress)246 public void setIpAddress(LinkAddress ipAddress) { 247 this.ipAddress = ipAddress; 248 } 249 getGateway()250 public InetAddress getGateway() { 251 return gateway; 252 } 253 setGateway(InetAddress gateway)254 public void setGateway(InetAddress gateway) { 255 this.gateway = gateway; 256 } 257 getDnsServers()258 public List<InetAddress> getDnsServers() { 259 return dnsServers; 260 } 261 262 /** 263 * Add a DNS server to this configuration. 264 */ addDnsServer(InetAddress server)265 public void addDnsServer(InetAddress server) { 266 dnsServers.add(server); 267 } 268 getDomains()269 public String getDomains() { 270 return domains; 271 } 272 setDomains(String domains)273 public void setDomains(String domains) { 274 this.domains = domains; 275 } 276 getServerAddress()277 public Inet4Address getServerAddress() { 278 return serverAddress; 279 } 280 setServerAddress(Inet4Address addr)281 public void setServerAddress(Inet4Address addr) { 282 serverAddress = addr; 283 } 284 getLeaseDuration()285 public int getLeaseDuration() { 286 return leaseDuration; 287 } 288 setLeaseDuration(int duration)289 public void setLeaseDuration(int duration) { 290 leaseDuration = duration; 291 } 292 getVendorInfo()293 public String getVendorInfo() { 294 return vendorInfo; 295 } 296 setVendorInfo(String info)297 public void setVendorInfo(String info) { 298 vendorInfo = info; 299 } 300 getMtu()301 public int getMtu() { 302 return mtu; 303 } 304 setMtu(int mtu)305 public void setMtu(int mtu) { 306 this.mtu = mtu; 307 } 308 } 309