1 /* 2 * Copyright (C) 2018 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.dhcp; 18 19 import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH; 20 21 import android.net.LinkAddress; 22 import android.util.ArraySet; 23 24 import androidx.annotation.NonNull; 25 import androidx.annotation.Nullable; 26 27 import java.net.Inet4Address; 28 import java.util.Collection; 29 import java.util.Collections; 30 import java.util.Set; 31 32 /** 33 * Subclass of {@link DhcpServingParamsParcel} with additional utility methods for building. 34 * 35 * <p>This utility class does not check for validity of the parameters: invalid parameters are 36 * reported by the receiving module when unparceling the parcel. 37 * 38 * @see DhcpServingParams 39 * @hide 40 */ 41 public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel { 42 public static final int MTU_UNSET = 0; 43 44 /** 45 * Set the server address and served prefix for the DHCP server. 46 * 47 * <p>This parameter is required. 48 */ setServerAddr(@onNull LinkAddress serverAddr)49 public DhcpServingParamsParcelExt setServerAddr(@NonNull LinkAddress serverAddr) { 50 this.serverAddr = inet4AddressToIntHTH((Inet4Address) serverAddr.getAddress()); 51 this.serverAddrPrefixLength = serverAddr.getPrefixLength(); 52 return this; 53 } 54 55 /** 56 * Set the default routers to be advertised to DHCP clients. 57 * 58 * <p>Each router must be inside the served prefix. This may be an empty set, but it must 59 * always be set explicitly. 60 */ setDefaultRouters(@onNull Set<Inet4Address> defaultRouters)61 public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) { 62 this.defaultRouters = toIntArray(defaultRouters); 63 return this; 64 } 65 66 /** 67 * Set the default routers to be advertised to DHCP clients. 68 * 69 * <p>Each router must be inside the served prefix. This may be an empty list of routers, 70 * but it must always be set explicitly. 71 */ setDefaultRouters(@onNull Inet4Address... defaultRouters)72 public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Inet4Address... defaultRouters) { 73 return setDefaultRouters(newArraySet(defaultRouters)); 74 } 75 76 /** 77 * Convenience method to build the parameters with no default router. 78 * 79 * <p>Equivalent to calling {@link #setDefaultRouters(Inet4Address...)} with no address. 80 */ setNoDefaultRouter()81 public DhcpServingParamsParcelExt setNoDefaultRouter() { 82 return setDefaultRouters(); 83 } 84 85 /** 86 * Set the DNS servers to be advertised to DHCP clients. 87 * 88 * <p>This may be an empty set, but it must always be set explicitly. 89 */ setDnsServers(@onNull Set<Inet4Address> dnsServers)90 public DhcpServingParamsParcelExt setDnsServers(@NonNull Set<Inet4Address> dnsServers) { 91 this.dnsServers = toIntArray(dnsServers); 92 return this; 93 } 94 95 /** 96 * Set the DNS servers to be advertised to DHCP clients. 97 * 98 * <p>This may be an empty list of servers, but it must always be set explicitly. 99 */ setDnsServers(@onNull Inet4Address... dnsServers)100 public DhcpServingParamsParcelExt setDnsServers(@NonNull Inet4Address... dnsServers) { 101 return setDnsServers(newArraySet(dnsServers)); 102 } 103 104 /** 105 * Convenience method to build the parameters with no DNS server. 106 * 107 * <p>Equivalent to calling {@link #setDnsServers(Inet4Address...)} with no address. 108 */ setNoDnsServer()109 public DhcpServingParamsParcelExt setNoDnsServer() { 110 return setDnsServers(); 111 } 112 113 /** 114 * Set excluded addresses that the DHCP server is not allowed to assign to clients. 115 * 116 * <p>This parameter is optional. DNS servers and default routers are always excluded 117 * and do not need to be set here. 118 */ setExcludedAddrs(@onNull Set<Inet4Address> excludedAddrs)119 public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) { 120 this.excludedAddrs = toIntArray(excludedAddrs); 121 return this; 122 } 123 124 /** 125 * Set excluded addresses that the DHCP server is not allowed to assign to clients. 126 * 127 * <p>This parameter is optional. DNS servers and default routers are always excluded 128 * and do not need to be set here. 129 */ setExcludedAddrs(@onNull Inet4Address... excludedAddrs)130 public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) { 131 return setExcludedAddrs(newArraySet(excludedAddrs)); 132 } 133 134 /** 135 * Set the lease time for leases assigned by the DHCP server. 136 * 137 * <p>This parameter is required. 138 */ setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs)139 public DhcpServingParamsParcelExt setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) { 140 this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs; 141 return this; 142 } 143 144 /** 145 * Set the link MTU to be advertised to DHCP clients. 146 * 147 * <p>If set to {@link #MTU_UNSET}, no MTU will be advertised to clients. This parameter 148 * is optional and defaults to {@link #MTU_UNSET}. 149 */ setLinkMtu(int linkMtu)150 public DhcpServingParamsParcelExt setLinkMtu(int linkMtu) { 151 this.linkMtu = linkMtu; 152 return this; 153 } 154 155 /** 156 * Set whether the DHCP server should send the ANDROID_METERED vendor-specific option. 157 * 158 * <p>If not set, the default value is false. 159 */ setMetered(boolean metered)160 public DhcpServingParamsParcelExt setMetered(boolean metered) { 161 this.metered = metered; 162 return this; 163 } 164 165 /** 166 * Set the client address to tell DHCP server only offer this address. 167 * The client's prefix length is the same as server's. 168 * 169 * <p>If not set, the default value is null. 170 */ setSingleClientAddr(@ullable Inet4Address clientAddr)171 public DhcpServingParamsParcelExt setSingleClientAddr(@Nullable Inet4Address clientAddr) { 172 this.singleClientAddr = clientAddr == null ? 0 : inet4AddressToIntHTH(clientAddr); 173 return this; 174 } 175 176 /** 177 * Set whether the DHCP server should request a new prefix from IpServer when receiving 178 * DHCPDECLINE message in certain particular link (e.g. there is only one downstream USB 179 * tethering client). If it's false, process DHCPDECLINE message as RFC2131#4.3.3 suggests. 180 * 181 * <p>If not set, the default value is false. 182 */ setChangePrefixOnDecline(boolean changePrefixOnDecline)183 public DhcpServingParamsParcelExt setChangePrefixOnDecline(boolean changePrefixOnDecline) { 184 this.changePrefixOnDecline = changePrefixOnDecline; 185 return this; 186 } 187 toIntArray(@onNull Collection<Inet4Address> addrs)188 private static int[] toIntArray(@NonNull Collection<Inet4Address> addrs) { 189 int[] res = new int[addrs.size()]; 190 int i = 0; 191 for (Inet4Address addr : addrs) { 192 res[i] = inet4AddressToIntHTH(addr); 193 i++; 194 } 195 return res; 196 } 197 newArraySet(Inet4Address... addrs)198 private static ArraySet<Inet4Address> newArraySet(Inet4Address... addrs) { 199 ArraySet<Inet4Address> addrSet = new ArraySet<>(addrs.length); 200 Collections.addAll(addrSet, addrs); 201 return addrSet; 202 } 203 } 204