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
17package android.net;
18
19import android.net.NetworkUtils;
20import android.os.Parcel;
21import android.text.TextUtils;
22import android.util.Log;
23
24import java.net.Inet4Address;
25import java.util.Objects;
26
27/**
28 * A simple object for retrieving the results of a DHCP request.
29 * Optimized (attempted) for that jni interface
30 * TODO - remove when DhcpInfo is deprecated.  Move the remaining api to LinkProperties.
31 * @hide
32 */
33public class DhcpResults extends StaticIpConfiguration {
34    private static final String TAG = "DhcpResults";
35
36    public Inet4Address serverAddress;
37
38    /** Vendor specific information (from RFC 2132). */
39    public String vendorInfo;
40
41    public int leaseDuration;
42
43    /** Link MTU option. 0 means unset. */
44    public int mtu;
45
46    public DhcpResults() {
47        super();
48    }
49
50    public DhcpResults(StaticIpConfiguration source) {
51        super(source);
52    }
53
54    /** copy constructor */
55    public DhcpResults(DhcpResults source) {
56        super(source);
57
58        if (source != null) {
59            // All these are immutable, so no need to make copies.
60            serverAddress = source.serverAddress;
61            vendorInfo = source.vendorInfo;
62            leaseDuration = source.leaseDuration;
63            mtu = source.mtu;
64        }
65    }
66
67    /**
68     * Test if this DHCP lease includes vendor hint that network link is
69     * metered, and sensitive to heavy data transfers.
70     */
71    public boolean hasMeteredHint() {
72        if (vendorInfo != null) {
73            return vendorInfo.contains("ANDROID_METERED");
74        } else {
75            return false;
76        }
77    }
78
79    public void clear() {
80        super.clear();
81        vendorInfo = null;
82        leaseDuration = 0;
83        mtu = 0;
84    }
85
86    @Override
87    public String toString() {
88        StringBuffer str = new StringBuffer(super.toString());
89
90        str.append(" DHCP server ").append(serverAddress);
91        str.append(" Vendor info ").append(vendorInfo);
92        str.append(" lease ").append(leaseDuration).append(" seconds");
93        if (mtu != 0) str.append(" MTU ").append(mtu);
94
95        return str.toString();
96    }
97
98    @Override
99    public boolean equals(Object obj) {
100        if (this == obj) return true;
101
102        if (!(obj instanceof DhcpResults)) return false;
103
104        DhcpResults target = (DhcpResults)obj;
105
106        return super.equals((StaticIpConfiguration) obj) &&
107                Objects.equals(serverAddress, target.serverAddress) &&
108                Objects.equals(vendorInfo, target.vendorInfo) &&
109                leaseDuration == target.leaseDuration &&
110                mtu == target.mtu;
111    }
112
113    /** Implement the Parcelable interface */
114    public static final Creator<DhcpResults> CREATOR =
115        new Creator<DhcpResults>() {
116            public DhcpResults createFromParcel(Parcel in) {
117                DhcpResults dhcpResults = new DhcpResults();
118                readFromParcel(dhcpResults, in);
119                return dhcpResults;
120            }
121
122            public DhcpResults[] newArray(int size) {
123                return new DhcpResults[size];
124            }
125        };
126
127    /** Implement the Parcelable interface */
128    public void writeToParcel(Parcel dest, int flags) {
129        super.writeToParcel(dest, flags);
130        dest.writeInt(leaseDuration);
131        dest.writeInt(mtu);
132        NetworkUtils.parcelInetAddress(dest, serverAddress, flags);
133        dest.writeString(vendorInfo);
134    }
135
136    private static void readFromParcel(DhcpResults dhcpResults, Parcel in) {
137        StaticIpConfiguration.readFromParcel(dhcpResults, in);
138        dhcpResults.leaseDuration = in.readInt();
139        dhcpResults.mtu = in.readInt();
140        dhcpResults.serverAddress = (Inet4Address) NetworkUtils.unparcelInetAddress(in);
141        dhcpResults.vendorInfo = in.readString();
142    }
143
144    // Utils for jni population - false on success
145    // Not part of the superclass because they're only used by the JNI iterface to the DHCP daemon.
146    public boolean setIpAddress(String addrString, int prefixLength) {
147        try {
148            Inet4Address addr = (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
149            ipAddress = new LinkAddress(addr, prefixLength);
150        } catch (IllegalArgumentException|ClassCastException e) {
151            Log.e(TAG, "setIpAddress failed with addrString " + addrString + "/" + prefixLength);
152            return true;
153        }
154        return false;
155    }
156
157    public boolean setGateway(String addrString) {
158        try {
159            gateway = NetworkUtils.numericToInetAddress(addrString);
160        } catch (IllegalArgumentException e) {
161            Log.e(TAG, "setGateway failed with addrString " + addrString);
162            return true;
163        }
164        return false;
165    }
166
167    public boolean addDns(String addrString) {
168        if (TextUtils.isEmpty(addrString) == false) {
169            try {
170                dnsServers.add(NetworkUtils.numericToInetAddress(addrString));
171            } catch (IllegalArgumentException e) {
172                Log.e(TAG, "addDns failed with addrString " + addrString);
173                return true;
174            }
175        }
176        return false;
177    }
178
179    public boolean setServerAddress(String addrString) {
180        try {
181            serverAddress = (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
182        } catch (IllegalArgumentException|ClassCastException e) {
183            Log.e(TAG, "setServerAddress failed with addrString " + addrString);
184            return true;
185        }
186        return false;
187    }
188
189    public void setLeaseDuration(int duration) {
190        leaseDuration = duration;
191    }
192
193    public void setVendorInfo(String info) {
194        vendorInfo = info;
195    }
196
197    public void setDomains(String newDomains) {
198        domains = newDomains;
199    }
200}
201