diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 599ccb2..34e9476 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -22,6 +22,7 @@
 import android.util.Pair;
 
 import java.io.FileDescriptor;
+import java.io.IOException;
 import java.math.BigInteger;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
@@ -131,6 +132,17 @@
     public native static boolean queryUserAccess(int uid, int netId);
 
     /**
+     * Add an entry into the ARP cache.
+     */
+    public static void addArpEntry(Inet4Address ipv4Addr, MacAddress ethAddr, String ifname,
+            FileDescriptor fd) throws IOException {
+        addArpEntry(ethAddr.toByteArray(), ipv4Addr.getAddress(), ifname, fd);
+    }
+
+    private static native void addArpEntry(byte[] ethAddr, byte[] netAddr, String ifname,
+            FileDescriptor fd) throws IOException;
+
+    /**
      * @see #intToInet4AddressHTL(int)
      * @deprecated Use either {@link #intToInet4AddressHTH(int)}
      *             or {@link #intToInet4AddressHTL(int)}
@@ -149,7 +161,7 @@
      * @param hostAddress an int coding for an IPv4 address, where higher-order int byte is
      *                    lower-order IPv4 address byte
      */
-    public static InetAddress intToInet4AddressHTL(int hostAddress) {
+    public static Inet4Address intToInet4AddressHTL(int hostAddress) {
         return intToInet4AddressHTH(Integer.reverseBytes(hostAddress));
     }
 
@@ -157,14 +169,14 @@
      * Convert a IPv4 address from an integer to an InetAddress (0x01020304 -> 1.2.3.4)
      * @param hostAddress an int coding for an IPv4 address
      */
-    public static InetAddress intToInet4AddressHTH(int hostAddress) {
+    public static Inet4Address intToInet4AddressHTH(int hostAddress) {
         byte[] addressBytes = { (byte) (0xff & (hostAddress >> 24)),
                 (byte) (0xff & (hostAddress >> 16)),
                 (byte) (0xff & (hostAddress >> 8)),
                 (byte) (0xff & hostAddress) };
 
         try {
-            return InetAddress.getByAddress(addressBytes);
+            return (Inet4Address) InetAddress.getByAddress(addressBytes);
         } catch (UnknownHostException e) {
             throw new AssertionError();
         }
@@ -397,6 +409,28 @@
     }
 
     /**
+     * Get a prefix mask as Inet4Address for a given prefix length.
+     *
+     * <p>For example 20 -> 255.255.240.0
+     */
+    public static Inet4Address getPrefixMaskAsInet4Address(int prefixLength)
+            throws IllegalArgumentException {
+        return intToInet4AddressHTH(prefixLengthToV4NetmaskIntHTH(prefixLength));
+    }
+
+    /**
+     * Get the broadcast address for a given prefix.
+     *
+     * <p>For example 192.168.0.1/24 -> 192.168.0.255
+     */
+    public static Inet4Address getBroadcastAddress(Inet4Address addr, int prefixLength)
+            throws IllegalArgumentException {
+        final int intBroadcastAddr = inet4AddressToIntHTH(addr)
+                | ~prefixLengthToV4NetmaskIntHTH(prefixLength);
+        return intToInet4AddressHTH(intBroadcastAddr);
+    }
+
+    /**
      * Check if IP address type is consistent between two InetAddress.
      * @return true if both are the same type.  False otherwise.
      */
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 823f1cc..9b138eb 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -323,6 +323,55 @@
     return (jboolean) !queryUserAccess(uid, netId);
 }
 
+static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst)
+{
+    if (env->GetArrayLength(addr) != len) {
+        return false;
+    }
+    env->GetByteArrayRegion(addr, 0, len, reinterpret_cast<jbyte*>(dst));
+    return true;
+}
+
+static void android_net_utils_addArpEntry(JNIEnv *env, jobject thiz, jbyteArray ethAddr,
+        jbyteArray ipv4Addr, jstring ifname, jobject javaFd)
+{
+    struct arpreq req = {};
+    struct sockaddr_in& netAddrStruct = *reinterpret_cast<sockaddr_in*>(&req.arp_pa);
+    struct sockaddr& ethAddrStruct = req.arp_ha;
+
+    ethAddrStruct.sa_family = ARPHRD_ETHER;
+    if (!checkLenAndCopy(env, ethAddr, ETH_ALEN, ethAddrStruct.sa_data)) {
+        jniThrowException(env, "java/io/IOException", "Invalid ethAddr length");
+        return;
+    }
+
+    netAddrStruct.sin_family = AF_INET;
+    if (!checkLenAndCopy(env, ipv4Addr, sizeof(in_addr), &netAddrStruct.sin_addr)) {
+        jniThrowException(env, "java/io/IOException", "Invalid ipv4Addr length");
+        return;
+    }
+
+    int ifLen = env->GetStringLength(ifname);
+    // IFNAMSIZ includes the terminating NULL character
+    if (ifLen >= IFNAMSIZ) {
+        jniThrowException(env, "java/io/IOException", "ifname too long");
+        return;
+    }
+    env->GetStringUTFRegion(ifname, 0, ifLen, req.arp_dev);
+
+    req.arp_flags = ATF_COM;  // Completed entry (ha valid)
+    int fd = jniGetFDFromFileDescriptor(env, javaFd);
+    if (fd < 0) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
+        return;
+    }
+    // See also: man 7 arp
+    if (ioctl(fd, SIOCSARP, &req)) {
+        jniThrowExceptionFmt(env, "java/io/IOException", "ioctl error: %s", strerror(errno));
+        return;
+    }
+}
+
 
 // ----------------------------------------------------------------------------
 
@@ -337,6 +386,7 @@
     { "bindSocketToNetwork", "(II)I", (void*) android_net_utils_bindSocketToNetwork },
     { "protectFromVpn", "(I)Z", (void*)android_net_utils_protectFromVpn },
     { "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
+    { "addArpEntry", "([B[BLjava/lang/String;Ljava/io/FileDescriptor;)V", (void*) android_net_utils_addArpEntry },
     { "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter },
     { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachRaFilter },
     { "attachControlPacketFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachControlPacketFilter },
diff --git a/services/net/java/android/net/dhcp/DhcpDiscoverPacket.java b/services/net/java/android/net/dhcp/DhcpDiscoverPacket.java
index 91e6bd6..11f2b61 100644
--- a/services/net/java/android/net/dhcp/DhcpDiscoverPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpDiscoverPacket.java
@@ -24,10 +24,17 @@
  */
 class DhcpDiscoverPacket extends DhcpPacket {
     /**
+     * The IP address of the client which sent this packet.
+     */
+    final Inet4Address mSrcIp;
+
+    /**
      * Generates a DISCOVER packet with the specified parameters.
      */
-    DhcpDiscoverPacket(int transId, short secs, byte[] clientMac, boolean broadcast) {
-        super(transId, secs, INADDR_ANY, INADDR_ANY, INADDR_ANY, INADDR_ANY, clientMac, broadcast);
+    DhcpDiscoverPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
+            boolean broadcast, Inet4Address srcIp) {
+        super(transId, secs, INADDR_ANY, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
+        mSrcIp = srcIp;
     }
 
     public String toString() {
@@ -41,8 +48,8 @@
      */
     public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
         ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        fillInPacket(encap, INADDR_BROADCAST, INADDR_ANY, destUdp,
-                srcUdp, result, DHCP_BOOTREQUEST, mBroadcast);
+        fillInPacket(encap, INADDR_BROADCAST, mSrcIp, destUdp, srcUdp, result, DHCP_BOOTREQUEST,
+                mBroadcast);
         result.flip();
         return result;
     }
diff --git a/services/net/java/android/net/dhcp/DhcpLease.java b/services/net/java/android/net/dhcp/DhcpLease.java
new file mode 100644
index 0000000..d2a15b3
--- /dev/null
+++ b/services/net/java/android/net/dhcp/DhcpLease.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.dhcp;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.os.SystemClock;
+import android.text.TextUtils;
+
+import com.android.internal.util.HexDump;
+
+import java.net.Inet4Address;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * An IPv4 address assignment done through DHCPv4.
+ * @hide
+ */
+public class DhcpLease {
+    public static final long EXPIRATION_NEVER = Long.MAX_VALUE;
+    public static final String HOSTNAME_NONE = null;
+
+    @Nullable
+    private final byte[] mClientId;
+    @NonNull
+    private final MacAddress mHwAddr;
+    @NonNull
+    private final Inet4Address mNetAddr;
+    /**
+     * Expiration time for the lease, to compare with {@link SystemClock#elapsedRealtime()}.
+     */
+    private final long mExpTime;
+    @Nullable
+    private final String mHostname;
+
+    public DhcpLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
+            @NonNull Inet4Address netAddr, long expTime, @Nullable String hostname) {
+        mClientId = (clientId == null ? null : Arrays.copyOf(clientId, clientId.length));
+        mHwAddr = hwAddr;
+        mNetAddr = netAddr;
+        mExpTime = expTime;
+        mHostname = hostname;
+    }
+
+    @Nullable
+    public byte[] getClientId() {
+        if (mClientId == null) {
+            return null;
+        }
+        return Arrays.copyOf(mClientId, mClientId.length);
+    }
+
+    @NonNull
+    public MacAddress getHwAddr() {
+        return mHwAddr;
+    }
+
+    @Nullable
+    public String getHostname() {
+        return mHostname;
+    }
+
+    @NonNull
+    public Inet4Address getNetAddr() {
+        return mNetAddr;
+    }
+
+    public long getExpTime() {
+        return mExpTime;
+    }
+
+    /**
+     * Push back the expiration time of this lease. If the provided time is sooner than the original
+     * expiration time, the lease time will not be updated.
+     *
+     * <p>The lease hostname is updated with the provided one if set.
+     * @return A {@link DhcpLease} with expiration time set to max(expTime, currentExpTime)
+     */
+    public DhcpLease renewedLease(long expTime, @Nullable String hostname) {
+        return new DhcpLease(mClientId, mHwAddr, mNetAddr, Math.max(expTime, mExpTime),
+                (hostname == null ? mHostname : hostname));
+    }
+
+    public boolean matchesClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) {
+        if (mClientId != null) {
+            return Arrays.equals(mClientId, clientId);
+        } else {
+            return clientId == null && mHwAddr.equals(hwAddr);
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof DhcpLease)) {
+            return false;
+        }
+        final DhcpLease other = (DhcpLease)obj;
+        return Arrays.equals(mClientId, other.mClientId)
+                && mHwAddr.equals(other.mHwAddr)
+                && mNetAddr.equals(other.mNetAddr)
+                && mExpTime == other.mExpTime
+                && TextUtils.equals(mHostname, other.mHostname);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mClientId, mHwAddr, mNetAddr, mHostname, mExpTime);
+    }
+
+    static String clientIdToString(byte[] bytes) {
+        if (bytes == null) {
+            return "null";
+        }
+        return HexDump.toHexString(bytes);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("clientId: %s, hwAddr: %s, netAddr: %s, expTime: %d, hostname: %s",
+                clientIdToString(mClientId), mHwAddr.toString(), mNetAddr, mExpTime, mHostname);
+    }
+}
diff --git a/services/net/java/android/net/dhcp/DhcpLeaseRepository.java b/services/net/java/android/net/dhcp/DhcpLeaseRepository.java
new file mode 100644
index 0000000..7e57c9f
--- /dev/null
+++ b/services/net/java/android/net/dhcp/DhcpLeaseRepository.java
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.dhcp;
+
+import static android.net.NetworkUtils.inet4AddressToIntHTH;
+import static android.net.NetworkUtils.intToInet4AddressHTH;
+import static android.net.NetworkUtils.prefixLengthToV4NetmaskIntHTH;
+import static android.net.dhcp.DhcpLease.EXPIRATION_NEVER;
+import static android.net.util.NetworkConstants.IPV4_ADDR_BITS;
+
+import static java.lang.Math.min;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.IpPrefix;
+import android.net.MacAddress;
+import android.net.util.SharedLog;
+import android.os.SystemClock;
+import android.util.ArrayMap;
+
+import java.net.Inet4Address;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.function.Function;
+
+/**
+ * A repository managing IPv4 address assignments through DHCPv4.
+ *
+ * <p>This class is not thread-safe. All public methods should be called on a common thread or
+ * use some synchronization mechanism.
+ *
+ * <p>Methods are optimized for a small number of allocated leases, assuming that most of the time
+ * only 2~10 addresses will be allocated, which is the common case. Managing a large number of
+ * addresses is supported but will be slower: some operations have complexity in O(num_leases).
+ * @hide
+ */
+class DhcpLeaseRepository {
+    public static final byte[] CLIENTID_UNSPEC = null;
+    public static final Inet4Address INETADDR_UNSPEC = null;
+
+    @NonNull
+    private final SharedLog mLog;
+    @NonNull
+    private final Clock mClock;
+
+    @NonNull
+    private IpPrefix mPrefix;
+    @NonNull
+    private Set<Inet4Address> mReservedAddrs;
+    private int mSubnetAddr;
+    private int mSubnetMask;
+    private int mNumAddresses;
+    private long mLeaseTimeMs;
+
+    public static class Clock {
+        /**
+         * @see SystemClock#elapsedRealtime()
+         */
+        public long elapsedRealtime() {
+            return SystemClock.elapsedRealtime();
+        }
+    }
+
+    /**
+     * Next timestamp when committed or declined leases should be checked for expired ones. This
+     * will always be lower than or equal to the time for the first lease to expire: it's OK not to
+     * update this when removing entries, but it must always be updated when adding/updating.
+     */
+    private long mNextExpirationCheck = EXPIRATION_NEVER;
+
+    static class DhcpLeaseException extends Exception {
+        DhcpLeaseException(String message) {
+            super(message);
+        }
+    }
+
+    static class OutOfAddressesException extends DhcpLeaseException {
+        OutOfAddressesException(String message) {
+            super(message);
+        }
+    }
+
+    static class InvalidAddressException extends DhcpLeaseException {
+        InvalidAddressException(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * Leases by IP address
+     */
+    private final ArrayMap<Inet4Address, DhcpLease> mCommittedLeases = new ArrayMap<>();
+
+    /**
+     * Map address -> expiration timestamp in ms. Addresses are guaranteed to be valid as defined
+     * by {@link #isValidAddress(Inet4Address)}, but are not necessarily otherwise available for
+     * assignment.
+     */
+    private final LinkedHashMap<Inet4Address, Long> mDeclinedAddrs = new LinkedHashMap<>();
+
+    public DhcpLeaseRepository(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
+            long leaseTimeMs, @NonNull SharedLog log, @NonNull Clock clock) {
+        updateParams(prefix, reservedAddrs, leaseTimeMs);
+        mLog = log;
+        mClock = clock;
+    }
+
+    public void updateParams(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
+            long leaseTimeMs) {
+        mPrefix = prefix;
+        mReservedAddrs = Collections.unmodifiableSet(new HashSet<>(reservedAddrs));
+        mSubnetMask = prefixLengthToV4NetmaskIntHTH(prefix.getPrefixLength());
+        mSubnetAddr = inet4AddressToIntHTH((Inet4Address) prefix.getAddress()) & mSubnetMask;
+        mNumAddresses = 1 << (IPV4_ADDR_BITS - prefix.getPrefixLength());
+        mLeaseTimeMs = leaseTimeMs;
+
+        cleanMap(mCommittedLeases);
+        cleanMap(mDeclinedAddrs);
+    }
+
+    /**
+     * From a map keyed by {@link Inet4Address}, remove entries where the key is invalid (as
+     * specified by {@link #isValidAddress(Inet4Address)}), or is a reserved address.
+     */
+    private <T> void cleanMap(Map<Inet4Address, T> map) {
+        final Iterator<Entry<Inet4Address, T>> it = map.entrySet().iterator();
+        while (it.hasNext()) {
+            final Inet4Address addr = it.next().getKey();
+            if (!isValidAddress(addr) || mReservedAddrs.contains(addr)) {
+                it.remove();
+            }
+        }
+    }
+
+    /**
+     * Get a DHCP offer, to reply to a DHCPDISCOVER. Follows RFC2131 #4.3.1.
+     *
+     * @param clientId Client identifier option if specified, or {@link #CLIENTID_UNSPEC}
+     * @param relayAddr Internet address of the relay (giaddr), can be {@link Inet4Address#ANY}
+     * @param reqAddr Requested address by the client (option 50), or {@link #INETADDR_UNSPEC}
+     * @param hostname Client-provided hostname, or {@link DhcpLease#HOSTNAME_NONE}
+     * @throws OutOfAddressesException The server does not have any available address
+     * @throws InvalidAddressException The lease was requested from an unsupported subnet
+     */
+    @NonNull
+    public DhcpLease getOffer(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
+            @NonNull Inet4Address relayAddr,
+            @Nullable Inet4Address reqAddr, @Nullable String hostname)
+            throws OutOfAddressesException, InvalidAddressException {
+        final long currentTime = mClock.elapsedRealtime();
+        final long expTime = currentTime + mLeaseTimeMs;
+
+        removeExpiredLeases(currentTime);
+
+        // As per #4.3.1, addresses are assigned based on the relay address if present. This
+        // implementation only assigns addresses if the relayAddr is inside our configured subnet.
+        // This also applies when the client requested a specific address for consistency between
+        // requests, and with older behavior.
+        if (isIpAddrOutsidePrefix(mPrefix, relayAddr)) {
+            throw new InvalidAddressException("Lease requested by relay from outside of subnet");
+        }
+
+        final DhcpLease currentLease = findByClient(clientId, hwAddr);
+        final DhcpLease newLease;
+        if (currentLease != null) {
+            newLease = currentLease.renewedLease(expTime, hostname);
+            mLog.log("Offering extended lease " + newLease);
+            // Do not update lease time in the map: the offer is not committed yet.
+        } else if (reqAddr != null && isValidAddress(reqAddr) && isAvailable(reqAddr)) {
+            newLease = new DhcpLease(clientId, hwAddr, reqAddr, expTime, hostname);
+            mLog.log("Offering requested lease " + newLease);
+        } else {
+            newLease = makeNewOffer(clientId, hwAddr, expTime, hostname);
+            mLog.log("Offering new generated lease " + newLease);
+        }
+        return newLease;
+    }
+
+    private static boolean isIpAddrOutsidePrefix(IpPrefix prefix, Inet4Address addr) {
+        return addr != null && !addr.equals(Inet4Address.ANY) && !prefix.contains(addr);
+    }
+
+    @Nullable
+    private DhcpLease findByClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) {
+        for (DhcpLease lease : mCommittedLeases.values()) {
+            if (lease.matchesClient(clientId, hwAddr)) {
+                return lease;
+            }
+        }
+
+        // Note this differs from dnsmasq behavior, which would match by hwAddr if clientId was
+        // given but no lease keyed on clientId matched. This would prevent one interface from
+        // obtaining multiple leases with different clientId.
+        return null;
+    }
+
+    /**
+     * Make a lease conformant to a client DHCPREQUEST or renew the client's existing lease,
+     * commit it to the repository and return it.
+     *
+     * <p>This method always succeeds and commits the lease if it does not throw, and has no side
+     * effects if it throws.
+     *
+     * @param clientId Client identifier option if specified, or {@link #CLIENTID_UNSPEC}
+     * @param reqAddr Requested address by the client (option 50), or {@link #INETADDR_UNSPEC}
+     * @param sidSet Whether the server identifier was set in the request
+     * @return The newly created or renewed lease
+     * @throws InvalidAddressException The client provided an address that conflicts with its
+     *                                 current configuration, or other committed/reserved leases.
+     */
+    @NonNull
+    public DhcpLease requestLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
+            @NonNull Inet4Address clientAddr, @Nullable Inet4Address reqAddr, boolean sidSet,
+            @Nullable String hostname) throws InvalidAddressException {
+        final long currentTime = mClock.elapsedRealtime();
+        removeExpiredLeases(currentTime);
+        final DhcpLease assignedLease = findByClient(clientId, hwAddr);
+
+        final Inet4Address leaseAddr = reqAddr != null ? reqAddr : clientAddr;
+        if (assignedLease != null) {
+            if (sidSet && reqAddr != null) {
+                // Client in SELECTING state; remove any current lease before creating a new one.
+                mCommittedLeases.remove(assignedLease.getNetAddr());
+            } else if (!assignedLease.getNetAddr().equals(leaseAddr)) {
+                // reqAddr null (RENEWING/REBINDING): client renewing its own lease for clientAddr.
+                // reqAddr set with sid not set (INIT-REBOOT): client verifying configuration.
+                // In both cases, throw if clientAddr or reqAddr does not match the known lease.
+                throw new InvalidAddressException("Incorrect address for client in " +
+                        (reqAddr != null ? "INIT-REBOOT" : "RENEWING/REBINDING"));
+            }
+        }
+
+        // In the init-reboot case, RFC2131 #4.3.2 says that the server must not reply if
+        // assignedLease == null, but dnsmasq will let the client use the requested address if
+        // available, when configured with --dhcp-authoritative. This is preferable to avoid issues
+        // if the server lost the lease DB: the client would not get a reply because the server
+        // does not know their lease.
+        // Similarly in RENEWING/REBINDING state, create a lease when possible if the
+        // client-provided lease is unknown.
+        final DhcpLease lease =
+                checkClientAndMakeLease(clientId, hwAddr, leaseAddr, hostname, currentTime);
+        mLog.logf("DHCPREQUEST assignedLease %s, reqAddr=%s, sidSet=%s: created/renewed lease %s",
+                assignedLease, reqAddr, sidSet, lease);
+        return lease;
+    }
+
+    /**
+     * Check that the client can request the specified address, make or renew the lease if yes, and
+     * commit it.
+     *
+     * <p>This method always succeeds and returns the lease if it does not throw, and has no
+     * side-effect if it throws.
+     *
+     * @return The newly created or renewed, committed lease
+     * @throws InvalidAddressException The client provided an address that conflicts with its
+     *                                 current configuration, or other committed/reserved leases.
+     */
+    private DhcpLease checkClientAndMakeLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
+            @NonNull Inet4Address addr, @Nullable String hostname, long currentTime)
+            throws InvalidAddressException {
+        final long expTime = currentTime + mLeaseTimeMs;
+        final DhcpLease currentLease = mCommittedLeases.getOrDefault(addr, null);
+        if (currentLease != null && !currentLease.matchesClient(clientId, hwAddr)) {
+            throw new InvalidAddressException("Address in use");
+        }
+
+        final DhcpLease lease;
+        if (currentLease == null) {
+            if (isValidAddress(addr) && !mReservedAddrs.contains(addr)) {
+                lease = new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
+            } else {
+                throw new InvalidAddressException("Lease not found and address unavailable");
+            }
+        } else {
+            lease = currentLease.renewedLease(expTime, hostname);
+        }
+        commitLease(lease);
+        return lease;
+    }
+
+    private void commitLease(@NonNull DhcpLease lease) {
+        mCommittedLeases.put(lease.getNetAddr(), lease);
+        maybeUpdateEarliestExpiration(lease.getExpTime());
+    }
+
+    /**
+     * Delete a committed lease from the repository.
+     *
+     * @return true if a lease matching parameters was found.
+     */
+    public boolean releaseLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
+            @NonNull Inet4Address addr) {
+        final DhcpLease currentLease = mCommittedLeases.getOrDefault(addr, null);
+        if (currentLease == null) {
+            mLog.w("Could not release unknown lease for " + addr);
+            return false;
+        }
+        if (currentLease.matchesClient(clientId, hwAddr)) {
+            mCommittedLeases.remove(addr);
+            mLog.log("Released lease " + currentLease);
+            return true;
+        }
+        mLog.w(String.format("Not releasing lease %s: does not match client (cid %s, hwAddr %s)",
+                currentLease, DhcpLease.clientIdToString(clientId), hwAddr));
+        return false;
+    }
+
+    public void markLeaseDeclined(@NonNull Inet4Address addr) {
+        if (mDeclinedAddrs.containsKey(addr) || !isValidAddress(addr)) {
+            mLog.logf("Not marking %s as declined: already declined or not assignable", addr);
+            return;
+        }
+        final long expTime = mClock.elapsedRealtime() + mLeaseTimeMs;
+        mDeclinedAddrs.put(addr, expTime);
+        mLog.logf("Marked %s as declined expiring %d", addr, expTime);
+        maybeUpdateEarliestExpiration(expTime);
+    }
+
+    /**
+     * Get the list of currently valid committed leases in the repository.
+     */
+    @NonNull
+    public List<DhcpLease> getCommittedLeases() {
+        removeExpiredLeases(mClock.elapsedRealtime());
+        return new ArrayList<>(mCommittedLeases.values());
+    }
+
+    /**
+     * Get the set of addresses that have been marked as declined in the repository.
+     */
+    @NonNull
+    public Set<Inet4Address> getDeclinedAddresses() {
+        removeExpiredLeases(mClock.elapsedRealtime());
+        return new HashSet<>(mDeclinedAddrs.keySet());
+    }
+
+    /**
+     * Given the expiration time of a new committed lease or declined address, update
+     * {@link #mNextExpirationCheck} so it stays lower than or equal to the time for the first lease
+     * to expire.
+     */
+    private void maybeUpdateEarliestExpiration(long expTime) {
+        if (expTime < mNextExpirationCheck) {
+            mNextExpirationCheck = expTime;
+        }
+    }
+
+    /**
+     * Remove expired entries from a map keyed by {@link Inet4Address}.
+     *
+     * @param tag Type of lease in the map, for logging
+     * @param getExpTime Functor returning the expiration time for an object in the map.
+     *                   Must not return null.
+     * @return The lowest expiration time among entries remaining in the map
+     */
+    private <T> long removeExpired(long currentTime, @NonNull Map<Inet4Address, T> map,
+            @NonNull String tag, @NonNull Function<T, Long> getExpTime) {
+        final Iterator<Entry<Inet4Address, T>> it = map.entrySet().iterator();
+        long firstExpiration = EXPIRATION_NEVER;
+        while (it.hasNext()) {
+            final Entry<Inet4Address, T> lease = it.next();
+            final long expTime = getExpTime.apply(lease.getValue());
+            if (expTime <= currentTime) {
+                mLog.logf("Removing expired %s lease for %s (expTime=%s, currentTime=%s)",
+                        tag, lease.getKey(), expTime, currentTime);
+                it.remove();
+            } else {
+                firstExpiration = min(firstExpiration, expTime);
+            }
+        }
+        return firstExpiration;
+    }
+
+    /**
+     * Go through committed and declined leases and remove the expired ones.
+     */
+    private void removeExpiredLeases(long currentTime) {
+        if (currentTime < mNextExpirationCheck) {
+            return;
+        }
+
+        final long commExp = removeExpired(
+                currentTime, mCommittedLeases, "committed", DhcpLease::getExpTime);
+        final long declExp = removeExpired(
+                currentTime, mDeclinedAddrs, "declined", Function.identity());
+
+        mNextExpirationCheck = min(commExp, declExp);
+    }
+
+    private boolean isAvailable(@NonNull Inet4Address addr) {
+        return !mReservedAddrs.contains(addr) && !mCommittedLeases.containsKey(addr);
+    }
+
+    /**
+     * Get the 0-based index of an address in the subnet.
+     *
+     * <p>Given ordering of addresses 5.6.7.8 < 5.6.7.9 < 5.6.8.0, the index on a subnet is defined
+     * so that the first address is 0, the second 1, etc. For example on a /16, 192.168.0.0 -> 0,
+     * 192.168.0.1 -> 1, 192.168.1.0 -> 256
+     *
+     */
+    private int getAddrIndex(int addr) {
+        return addr & ~mSubnetMask;
+    }
+
+    private int getAddrByIndex(int index) {
+        return mSubnetAddr | index;
+    }
+
+    /**
+     * Get a valid address starting from the supplied one.
+     *
+     * <p>This only checks that the address is numerically valid for assignment, not whether it is
+     * already in use. The return value is always inside the configured prefix, even if the supplied
+     * address is not.
+     *
+     * <p>If the provided address is valid, it is returned as-is. Otherwise, the next valid
+     * address (with the ordering in {@link #getAddrIndex(int)}) is returned.
+     */
+    private int getValidAddress(int addr) {
+        final int lastByteMask = 0xff;
+        int addrIndex = getAddrIndex(addr); // 0-based index of the address in the subnet
+
+        // Some OSes do not handle addresses in .255 or .0 correctly: avoid those.
+        final int lastByte = getAddrByIndex(addrIndex) & lastByteMask;
+        if (lastByte == lastByteMask) {
+            // Avoid .255 address, and .0 address that follows
+            addrIndex = (addrIndex + 2) % mNumAddresses;
+        } else if (lastByte == 0) {
+            // Avoid .0 address
+            addrIndex = (addrIndex + 1) % mNumAddresses;
+        }
+
+        // Do not use first or last address of range
+        if (addrIndex == 0 || addrIndex == mNumAddresses - 1) {
+            // Always valid and not end of range since prefixLength is at most 30 in serving params
+            addrIndex = 1;
+        }
+        return getAddrByIndex(addrIndex);
+    }
+
+    /**
+     * Returns whether the address is in the configured subnet and part of the assignable range.
+     */
+    private boolean isValidAddress(Inet4Address addr) {
+        final int intAddr = inet4AddressToIntHTH(addr);
+        return getValidAddress(intAddr) == intAddr;
+    }
+
+    private int getNextAddress(int addr) {
+        final int addrIndex = getAddrIndex(addr);
+        final int nextAddress = getAddrByIndex((addrIndex + 1) % mNumAddresses);
+        return getValidAddress(nextAddress);
+    }
+
+    /**
+     * Calculate a first candidate address for a client by hashing the hardware address.
+     *
+     * <p>This will be a valid address as checked by {@link #getValidAddress(int)}, but may be
+     * in use.
+     *
+     * @return An IPv4 address encoded as 32-bit int
+     */
+    private int getFirstClientAddress(MacAddress hwAddr) {
+        // This follows dnsmasq behavior. Advantages are: clients will often get the same
+        // offers for different DISCOVER even if the lease was not yet accepted or has expired,
+        // and address generation will generally not need to loop through many allocated addresses
+        // until it finds a free one.
+        int hash = 0;
+        for (byte b : hwAddr.toByteArray()) {
+            hash += b + (b << 8) + (b << 16);
+        }
+        // This implementation will not always result in the same IPs as dnsmasq would give out in
+        // Android <= P, because it includes invalid and reserved addresses in mNumAddresses while
+        // the configured ranges for dnsmasq did not.
+        final int addrIndex = hash % mNumAddresses;
+        return getValidAddress(getAddrByIndex(addrIndex));
+    }
+
+    /**
+     * Create a lease that can be offered to respond to a client DISCOVER.
+     *
+     * <p>This method always succeeds and returns the lease if it does not throw. If no non-declined
+     * address is available, it will try to offer the oldest declined address if valid.
+     *
+     * @throws OutOfAddressesException The server has no address left to offer
+     */
+    private DhcpLease makeNewOffer(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
+            long expTime, @Nullable String hostname) throws OutOfAddressesException {
+        int intAddr = getFirstClientAddress(hwAddr);
+        // Loop until a free address is found, or there are no more addresses.
+        // There is slightly less than this many usable addresses, but some extra looping is OK
+        for (int i = 0; i < mNumAddresses; i++) {
+            final Inet4Address addr = intToInet4AddressHTH(intAddr);
+            if (isAvailable(addr) && !mDeclinedAddrs.containsKey(addr)) {
+                return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
+            }
+            intAddr = getNextAddress(intAddr);
+        }
+
+        // Try freeing DECLINEd addresses if out of addresses.
+        final Iterator<Inet4Address> it = mDeclinedAddrs.keySet().iterator();
+        while (it.hasNext()) {
+            final Inet4Address addr = it.next();
+            it.remove();
+            mLog.logf("Out of addresses in address pool: dropped declined addr %s", addr);
+            // isValidAddress() is always verified for entries in mDeclinedAddrs.
+            // However declined addresses may have been requested (typically by the machine that was
+            // already using the address) after being declined.
+            if (isAvailable(addr)) {
+                return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
+            }
+        }
+
+        throw new OutOfAddressesException("No address available for offer");
+    }
+}
diff --git a/services/net/java/android/net/dhcp/DhcpNakPacket.java b/services/net/java/android/net/dhcp/DhcpNakPacket.java
index 6458232..ef9af52 100644
--- a/services/net/java/android/net/dhcp/DhcpNakPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpNakPacket.java
@@ -26,11 +26,9 @@
     /**
      * Generates a NAK packet with the specified parameters.
      */
-    DhcpNakPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                  Inet4Address nextIp, Inet4Address relayIp,
-                  byte[] clientMac) {
-        super(transId, secs, INADDR_ANY, INADDR_ANY, nextIp, relayIp,
-            clientMac, false);
+    DhcpNakPacket(int transId, short secs, Inet4Address nextIp, Inet4Address relayIp,
+            byte[] clientMac, boolean broadcast) {
+        super(transId, secs, INADDR_ANY, INADDR_ANY, nextIp, relayIp, clientMac, broadcast);
     }
 
     public String toString() {
@@ -43,11 +41,11 @@
      */
     public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
         ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        Inet4Address destIp = mClientIp;
-        Inet4Address srcIp = mYourIp;
+        // Constructor does not set values for layers <= 3: use empty values
+        Inet4Address destIp = INADDR_ANY;
+        Inet4Address srcIp = INADDR_ANY;
 
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
-            DHCP_BOOTREPLY, mBroadcast);
+        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result, DHCP_BOOTREPLY, mBroadcast);
         result.flip();
         return result;
     }
diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java
index d90a4a2..888821a 100644
--- a/services/net/java/android/net/dhcp/DhcpPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpPacket.java
@@ -1,5 +1,6 @@
 package android.net.dhcp;
 
+import android.annotation.Nullable;
 import android.net.DhcpResults;
 import android.net.LinkAddress;
 import android.net.NetworkUtils;
@@ -204,6 +205,7 @@
     protected static final byte DHCP_MESSAGE_TYPE_DECLINE = 4;
     protected static final byte DHCP_MESSAGE_TYPE_ACK = 5;
     protected static final byte DHCP_MESSAGE_TYPE_NAK = 6;
+    protected static final byte DHCP_MESSAGE_TYPE_RELEASE = 7;
     protected static final byte DHCP_MESSAGE_TYPE_INFORM = 8;
 
     /**
@@ -252,6 +254,7 @@
      * DHCP Optional Type: DHCP Client Identifier
      */
     protected static final byte DHCP_CLIENT_IDENTIFIER = 61;
+    protected byte[] mClientId;
 
     /**
      * DHCP zero-length option code: pad
@@ -281,7 +284,7 @@
     protected final Inet4Address mClientIp;
     protected final Inet4Address mYourIp;
     private final Inet4Address mNextIp;
-    private final Inet4Address mRelayIp;
+    protected final Inet4Address mRelayIp;
 
     /**
      * Does the client request a broadcast response?
@@ -338,13 +341,28 @@
         return mClientMac;
     }
 
+    // TODO: refactor DhcpClient to set clientId when constructing packets and remove
+    // hasExplicitClientId logic
     /**
-     * Returns the client ID. This follows RFC 2132 and is based on the hardware address.
+     * Returns whether a client ID was set in the options for this packet.
+     */
+    public boolean hasExplicitClientId() {
+        return mClientId != null;
+    }
+
+    /**
+     * Returns the client ID. If not set explicitly, this follows RFC 2132 and creates a client ID
+     * based on the hardware address.
      */
     public byte[] getClientId() {
-        byte[] clientId = new byte[mClientMac.length + 1];
-        clientId[0] = CLIENT_ID_ETHER;
-        System.arraycopy(mClientMac, 0, clientId, 1, mClientMac.length);
+        final byte[] clientId;
+        if (hasExplicitClientId()) {
+            clientId = Arrays.copyOf(mClientId, mClientId.length);
+        } else {
+            clientId = new byte[mClientMac.length + 1];
+            clientId[0] = CLIENT_ID_ETHER;
+            System.arraycopy(mClientMac, 0, clientId, 1, mClientMac.length);
+        }
         return clientId;
     }
 
@@ -531,8 +549,10 @@
 
     /**
      * Adds an optional parameter containing an array of bytes.
+     *
+     * <p>This method is a no-op if the payload argument is null.
      */
-    protected static void addTlv(ByteBuffer buf, byte type, byte[] payload) {
+    protected static void addTlv(ByteBuffer buf, byte type, @Nullable byte[] payload) {
         if (payload != null) {
             if (payload.length > MAX_OPTION_LEN) {
                 throw new IllegalArgumentException("DHCP option too long: "
@@ -546,8 +566,10 @@
 
     /**
      * Adds an optional parameter containing an IP address.
+     *
+     * <p>This method is a no-op if the address argument is null.
      */
-    protected static void addTlv(ByteBuffer buf, byte type, Inet4Address addr) {
+    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Inet4Address addr) {
         if (addr != null) {
             addTlv(buf, type, addr.getAddress());
         }
@@ -555,8 +577,10 @@
 
     /**
      * Adds an optional parameter containing a list of IP addresses.
+     *
+     * <p>This method is a no-op if the addresses argument is null or empty.
      */
-    protected static void addTlv(ByteBuffer buf, byte type, List<Inet4Address> addrs) {
+    protected static void addTlv(ByteBuffer buf, byte type, @Nullable List<Inet4Address> addrs) {
         if (addrs == null || addrs.size() == 0) return;
 
         int optionLen = 4 * addrs.size();
@@ -574,9 +598,11 @@
     }
 
     /**
-     * Adds an optional parameter containing a short integer
+     * Adds an optional parameter containing a short integer.
+     *
+     * <p>This method is a no-op if the value argument is null.
      */
-    protected static void addTlv(ByteBuffer buf, byte type, Short value) {
+    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Short value) {
         if (value != null) {
             buf.put(type);
             buf.put((byte) 2);
@@ -585,9 +611,11 @@
     }
 
     /**
-     * Adds an optional parameter containing a simple integer
+     * Adds an optional parameter containing a simple integer.
+     *
+     * <p>This method is a no-op if the value argument is null.
      */
-    protected static void addTlv(ByteBuffer buf, byte type, Integer value) {
+    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Integer value) {
         if (value != null) {
             buf.put(type);
             buf.put((byte) 4);
@@ -597,12 +625,16 @@
 
     /**
      * Adds an optional parameter containing an ASCII string.
+     *
+     * <p>This method is a no-op if the string argument is null.
      */
-    protected static void addTlv(ByteBuffer buf, byte type, String str) {
-        try {
-            addTlv(buf, type, str.getBytes("US-ASCII"));
-        } catch (UnsupportedEncodingException e) {
-           throw new IllegalArgumentException("String is not US-ASCII: " + str);
+    protected static void addTlv(ByteBuffer buf, byte type, @Nullable String str) {
+        if (str != null) {
+            try {
+                addTlv(buf, type, str.getBytes("US-ASCII"));
+            } catch (UnsupportedEncodingException e) {
+                throw new IllegalArgumentException("String is not US-ASCII: " + str);
+            }
         }
     }
 
@@ -740,6 +772,7 @@
         Inet4Address nextIp;
         Inet4Address relayIp;
         byte[] clientMac;
+        byte[] clientId = null;
         List<Inet4Address> dnsServers = new ArrayList<>();
         List<Inet4Address> gateways = new ArrayList<>();  // aka router
         Inet4Address serverIdentifier = null;
@@ -1038,8 +1071,8 @@
                 throw new ParseException(DhcpErrorEvent.DHCP_NO_MSG_TYPE,
                         "No DHCP message type option");
             case DHCP_MESSAGE_TYPE_DISCOVER:
-                newPacket = new DhcpDiscoverPacket(
-                    transactionId, secs, clientMac, broadcast);
+                newPacket = new DhcpDiscoverPacket(transactionId, secs, relayIp, clientMac,
+                        broadcast, ipSrc);
                 break;
             case DHCP_MESSAGE_TYPE_OFFER:
                 newPacket = new DhcpOfferPacket(
@@ -1047,7 +1080,7 @@
                 break;
             case DHCP_MESSAGE_TYPE_REQUEST:
                 newPacket = new DhcpRequestPacket(
-                    transactionId, secs, clientIp, clientMac, broadcast);
+                    transactionId, secs, clientIp, relayIp, clientMac, broadcast);
                 break;
             case DHCP_MESSAGE_TYPE_DECLINE:
                 newPacket = new DhcpDeclinePacket(
@@ -1060,8 +1093,15 @@
                 break;
             case DHCP_MESSAGE_TYPE_NAK:
                 newPacket = new DhcpNakPacket(
-                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
-                    clientMac);
+                        transactionId, secs, nextIp, relayIp, clientMac, broadcast);
+                break;
+            case DHCP_MESSAGE_TYPE_RELEASE:
+                if (serverIdentifier == null) {
+                    throw new ParseException(DhcpErrorEvent.MISC_ERROR,
+                            "DHCPRELEASE without server identifier");
+                }
+                newPacket = new DhcpReleasePacket(
+                        transactionId, serverIdentifier, clientIp, relayIp, clientMac);
                 break;
             case DHCP_MESSAGE_TYPE_INFORM:
                 newPacket = new DhcpInformPacket(
@@ -1074,6 +1114,7 @@
         }
 
         newPacket.mBroadcastAddress = bcAddr;
+        newPacket.mClientId = clientId;
         newPacket.mDnsServers = dnsServers;
         newPacket.mDomainName = domainName;
         newPacket.mGateways = gateways;
@@ -1173,8 +1214,8 @@
      */
     public static ByteBuffer buildDiscoverPacket(int encap, int transactionId,
         short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams) {
-        DhcpPacket pkt = new DhcpDiscoverPacket(
-            transactionId, secs, clientMac, broadcast);
+        DhcpPacket pkt = new DhcpDiscoverPacket(transactionId, secs, INADDR_ANY /* relayIp */,
+                clientMac, broadcast, INADDR_ANY /* srcIp */);
         pkt.mRequestedParams = expectedParams;
         return pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT);
     }
@@ -1223,12 +1264,11 @@
     /**
      * Builds a DHCP-NAK packet from the required specified parameters.
      */
-    public static ByteBuffer buildNakPacket(int encap, int transactionId,
-        Inet4Address serverIpAddr, Inet4Address clientIpAddr, byte[] mac) {
-        DhcpPacket pkt = new DhcpNakPacket(transactionId, (short) 0, clientIpAddr,
-            serverIpAddr, serverIpAddr, serverIpAddr, mac);
-        pkt.mMessage = "requested address not available";
-        pkt.mRequestedIp = clientIpAddr;
+    public static ByteBuffer buildNakPacket(int encap, int transactionId, Inet4Address serverIpAddr,
+            byte[] mac, boolean broadcast, String message) {
+        DhcpPacket pkt = new DhcpNakPacket(
+                transactionId, (short) 0, serverIpAddr, serverIpAddr, mac, broadcast);
+        pkt.mMessage = message;
         return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
     }
 
@@ -1240,7 +1280,7 @@
         byte[] clientMac, Inet4Address requestedIpAddress,
         Inet4Address serverIdentifier, byte[] requestedParams, String hostName) {
         DhcpPacket pkt = new DhcpRequestPacket(transactionId, secs, clientIp,
-            clientMac, broadcast);
+                INADDR_ANY /* relayIp */, clientMac, broadcast);
         pkt.mRequestedIp = requestedIpAddress;
         pkt.mServerIdentifier = serverIdentifier;
         pkt.mHostName = hostName;
diff --git a/services/net/java/android/net/dhcp/DhcpPacketListener.java b/services/net/java/android/net/dhcp/DhcpPacketListener.java
new file mode 100644
index 0000000..498fd93
--- /dev/null
+++ b/services/net/java/android/net/dhcp/DhcpPacketListener.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.dhcp;
+
+import android.annotation.Nullable;
+import android.net.util.FdEventsReader;
+import android.net.util.PacketReader;
+import android.os.Handler;
+import android.system.Os;
+
+import java.io.FileDescriptor;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+/**
+ * A {@link FdEventsReader} to receive and parse {@link DhcpPacket}.
+ * @hide
+ */
+abstract class DhcpPacketListener extends FdEventsReader<DhcpPacketListener.Payload> {
+    static final class Payload {
+        final byte[] bytes = new byte[DhcpPacket.MAX_LENGTH];
+        Inet4Address srcAddr;
+    }
+
+    public DhcpPacketListener(Handler handler) {
+        super(handler, new Payload());
+    }
+
+    @Override
+    protected int recvBufSize(Payload buffer) {
+        return buffer.bytes.length;
+    }
+
+    @Override
+    protected final void handlePacket(Payload recvbuf, int length) {
+        if (recvbuf.srcAddr == null) {
+            return;
+        }
+
+        try {
+            final DhcpPacket packet = DhcpPacket.decodeFullPacket(recvbuf.bytes, length,
+                    DhcpPacket.ENCAP_BOOTP);
+            onReceive(packet, recvbuf.srcAddr);
+        } catch (DhcpPacket.ParseException e) {
+            logParseError(recvbuf.bytes, length, e);
+        }
+    }
+
+    @Override
+    protected int readPacket(FileDescriptor fd, Payload packetBuffer) throws Exception {
+        final InetSocketAddress addr = new InetSocketAddress();
+        final int read = Os.recvfrom(
+                fd, packetBuffer.bytes, 0, packetBuffer.bytes.length, 0 /* flags */, addr);
+
+        // Buffers with null srcAddr will be dropped in handlePacket()
+        packetBuffer.srcAddr = inet4AddrOrNull(addr);
+        return read;
+    }
+
+    @Nullable
+    private static Inet4Address inet4AddrOrNull(InetSocketAddress addr) {
+        return addr.getAddress() instanceof Inet4Address
+                ? (Inet4Address) addr.getAddress()
+                : null;
+    }
+
+    protected abstract void onReceive(DhcpPacket packet, Inet4Address srcAddr);
+    protected abstract void logParseError(byte[] packet, int length, DhcpPacket.ParseException e);
+}
diff --git a/services/net/java/android/net/dhcp/DhcpReleasePacket.java b/services/net/java/android/net/dhcp/DhcpReleasePacket.java
new file mode 100644
index 0000000..3958303
--- /dev/null
+++ b/services/net/java/android/net/dhcp/DhcpReleasePacket.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.dhcp;
+
+import java.net.Inet4Address;
+import java.nio.ByteBuffer;
+
+/**
+ * Implements DHCP-RELEASE
+ */
+class DhcpReleasePacket extends DhcpPacket {
+
+    final Inet4Address mClientAddr;
+
+    /**
+     * Generates a RELEASE packet with the specified parameters.
+     */
+    public DhcpReleasePacket(int transId, Inet4Address serverId, Inet4Address clientAddr,
+            Inet4Address relayIp, byte[] clientMac) {
+        super(transId, (short)0, clientAddr, INADDR_ANY /* yourIp */, INADDR_ANY /* nextIp */,
+                relayIp, clientMac, false /* broadcast */);
+        mServerIdentifier = serverId;
+        mClientAddr = clientAddr;
+    }
+
+
+    @Override
+    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
+        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
+        fillInPacket(encap, mServerIdentifier /* destIp */, mClientIp /* srcIp */, destUdp, srcUdp,
+                result, DHCP_BOOTREPLY, mBroadcast);
+        result.flip();
+        return result;
+    }
+
+    @Override
+    void finishPacket(ByteBuffer buffer) {
+        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_RELEASE);
+        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
+        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
+        addCommonClientTlvs(buffer);
+        addTlvEnd(buffer);
+    }
+}
diff --git a/services/net/java/android/net/dhcp/DhcpRequestPacket.java b/services/net/java/android/net/dhcp/DhcpRequestPacket.java
index 4f9aa01..231d0457 100644
--- a/services/net/java/android/net/dhcp/DhcpRequestPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpRequestPacket.java
@@ -28,9 +28,9 @@
     /**
      * Generates a REQUEST packet with the specified parameters.
      */
-    DhcpRequestPacket(int transId, short secs, Inet4Address clientIp, byte[] clientMac,
-                      boolean broadcast) {
-        super(transId, secs, clientIp, INADDR_ANY, INADDR_ANY, INADDR_ANY, clientMac, broadcast);
+    DhcpRequestPacket(int transId, short secs, Inet4Address clientIp, Inet4Address relayIp,
+            byte[] clientMac, boolean broadcast) {
+        super(transId, secs, clientIp, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
     }
 
     public String toString() {
diff --git a/services/net/java/android/net/dhcp/DhcpServingParams.java b/services/net/java/android/net/dhcp/DhcpServingParams.java
new file mode 100644
index 0000000..ba9d116
--- /dev/null
+++ b/services/net/java/android/net/dhcp/DhcpServingParams.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.dhcp;
+
+import static android.net.NetworkUtils.getPrefixMaskAsInet4Address;
+import static android.net.dhcp.DhcpPacket.INFINITE_LEASE;
+import static android.net.util.NetworkConstants.IPV4_MAX_MTU;
+import static android.net.util.NetworkConstants.IPV4_MIN_MTU;
+
+import static java.lang.Integer.toUnsignedLong;
+
+import android.annotation.NonNull;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+
+import java.net.Inet4Address;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Parameters used by the DhcpServer to serve requests.
+ *
+ * <p>Instances are immutable. Use {@link DhcpServingParams.Builder} to instantiate.
+ * @hide
+ */
+public class DhcpServingParams {
+    public static final int MTU_UNSET = 0;
+    public static final int MIN_PREFIX_LENGTH = 16;
+    public static final int MAX_PREFIX_LENGTH = 30;
+
+    /** Server inet address and prefix to serve */
+    @NonNull
+    public final LinkAddress serverAddr;
+
+    /**
+     * Default routers to be advertised to DHCP clients. May be empty.
+     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
+     */
+    @NonNull
+    public final Set<Inet4Address> defaultRouters;
+
+    /**
+     * DNS servers to be advertised to DHCP clients. May be empty.
+     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
+     */
+    @NonNull
+    public final Set<Inet4Address> dnsServers;
+
+    /**
+     * Excluded addresses that the DHCP server is not allowed to assign to clients.
+     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
+     */
+    @NonNull
+    public final Set<Inet4Address> excludedAddrs;
+
+    // DHCP uses uint32. Use long for clearer code, and check range when building.
+    public final long dhcpLeaseTimeSecs;
+    public final int linkMtu;
+
+    /**
+     * Checked exception thrown when some parameters used to build {@link DhcpServingParams} are
+     * missing or invalid.
+     */
+    public static class InvalidParameterException extends Exception {
+        public InvalidParameterException(String message) {
+            super(message);
+        }
+    }
+
+    private DhcpServingParams(@NonNull LinkAddress serverAddr,
+            @NonNull Set<Inet4Address> defaultRouters,
+            @NonNull Set<Inet4Address> dnsServers, @NonNull Set<Inet4Address> excludedAddrs,
+            long dhcpLeaseTimeSecs, int linkMtu) {
+        this.serverAddr = serverAddr;
+        this.defaultRouters = defaultRouters;
+        this.dnsServers = dnsServers;
+        this.excludedAddrs = excludedAddrs;
+        this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
+        this.linkMtu = linkMtu;
+    }
+
+    @NonNull
+    public Inet4Address getServerInet4Addr() {
+        return (Inet4Address) serverAddr.getAddress();
+    }
+
+    /**
+     * Get the served prefix mask as an IPv4 address.
+     *
+     * <p>For example, if the served prefix is 192.168.42.0/24, this will return 255.255.255.0.
+     */
+    @NonNull
+    public Inet4Address getPrefixMaskAsAddress() {
+        return getPrefixMaskAsInet4Address(serverAddr.getPrefixLength());
+    }
+
+    /**
+     * Get the server broadcast address.
+     *
+     * <p>For example, if the server {@link LinkAddress} is 192.168.42.1/24, this will return
+     * 192.168.42.255.
+     */
+    @NonNull
+    public Inet4Address getBroadcastAddress() {
+        return NetworkUtils.getBroadcastAddress(getServerInet4Addr(), serverAddr.getPrefixLength());
+    }
+
+    /**
+     * Utility class to create new instances of {@link DhcpServingParams} while checking validity
+     * of the parameters.
+     */
+    public static class Builder {
+        private LinkAddress serverAddr;
+        private Set<Inet4Address> defaultRouters;
+        private Set<Inet4Address> dnsServers;
+        private Set<Inet4Address> excludedAddrs;
+        private long dhcpLeaseTimeSecs;
+        private int linkMtu = MTU_UNSET;
+
+        /**
+         * Set the server address and served prefix for the DHCP server.
+         *
+         * <p>This parameter is required.
+         */
+        public Builder setServerAddr(@NonNull LinkAddress serverAddr) {
+            this.serverAddr = serverAddr;
+            return this;
+        }
+
+        /**
+         * Set the default routers to be advertised to DHCP clients.
+         *
+         * <p>Each router must be inside the served prefix. This may be an empty set, but it must
+         * always be set explicitly before building the {@link DhcpServingParams}.
+         */
+        public Builder setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) {
+            this.defaultRouters = defaultRouters;
+            return this;
+        }
+
+        /**
+         * Set the DNS servers to be advertised to DHCP clients.
+         *
+         * <p>This may be an empty set, but it must always be set explicitly before building the
+         * {@link DhcpServingParams}.
+         */
+        public Builder setDnsServers(@NonNull Set<Inet4Address> dnsServers) {
+            this.dnsServers = dnsServers;
+            return this;
+        }
+
+        /**
+         * Set excluded addresses that the DHCP server is not allowed to assign to clients.
+         *
+         * <p>This parameter is optional. DNS servers and default routers are always excluded
+         * and do not need to be set here.
+         */
+        public Builder setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) {
+            this.excludedAddrs = excludedAddrs;
+            return this;
+        }
+
+        /**
+         * Set the lease time for leases assigned by the DHCP server.
+         *
+         * <p>This parameter is required.
+         */
+        public Builder setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) {
+            this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
+            return this;
+        }
+
+        /**
+         * Set the link MTU to be advertised to DHCP clients.
+         *
+         * <p>If set to {@link #MTU_UNSET}, no MTU will be advertised to clients. This parameter
+         * is optional and defaults to {@link #MTU_UNSET}.
+         */
+        public Builder setLinkMtu(int linkMtu) {
+            this.linkMtu = linkMtu;
+            return this;
+        }
+
+        /**
+         * Create a new {@link DhcpServingParams} instance based on parameters set in the builder.
+         *
+         * <p>This method has no side-effects. If it does not throw, a valid
+         * {@link DhcpServingParams} is returned.
+         * @return The constructed parameters.
+         * @throws InvalidParameterException At least one parameter is missing or invalid.
+         */
+        @NonNull
+        public DhcpServingParams build() throws InvalidParameterException {
+            if (serverAddr == null) {
+                throw new InvalidParameterException("Missing serverAddr");
+            }
+            if (defaultRouters == null) {
+                throw new InvalidParameterException("Missing defaultRouters");
+            }
+            if (dnsServers == null) {
+                // Empty set is OK, but enforce explicitly setting it
+                throw new InvalidParameterException("Missing dnsServers");
+            }
+            if (dhcpLeaseTimeSecs <= 0 || dhcpLeaseTimeSecs > toUnsignedLong(INFINITE_LEASE)) {
+                throw new InvalidParameterException("Invalid lease time: " + dhcpLeaseTimeSecs);
+            }
+            if (linkMtu != MTU_UNSET && (linkMtu < IPV4_MIN_MTU || linkMtu > IPV4_MAX_MTU)) {
+                throw new InvalidParameterException("Invalid link MTU: " + linkMtu);
+            }
+            if (!serverAddr.isIPv4()) {
+                throw new InvalidParameterException("serverAddr must be IPv4");
+            }
+            if (serverAddr.getPrefixLength() < MIN_PREFIX_LENGTH
+                    || serverAddr.getPrefixLength() > MAX_PREFIX_LENGTH) {
+                throw new InvalidParameterException("Prefix length is not in supported range");
+            }
+
+            final IpPrefix prefix = makeIpPrefix(serverAddr);
+            for (Inet4Address addr : defaultRouters) {
+                if (!prefix.contains(addr)) {
+                    throw new InvalidParameterException(String.format(
+                            "Default router %s is not in server prefix %s", addr, serverAddr));
+                }
+            }
+
+            final Set<Inet4Address> excl = new HashSet<>();
+            if (excludedAddrs != null) {
+                excl.addAll(excludedAddrs);
+            }
+            excl.add((Inet4Address) serverAddr.getAddress());
+            excl.addAll(defaultRouters);
+            excl.addAll(dnsServers);
+
+            return new DhcpServingParams(serverAddr,
+                    Collections.unmodifiableSet(new HashSet<>(defaultRouters)),
+                    Collections.unmodifiableSet(new HashSet<>(dnsServers)),
+                    Collections.unmodifiableSet(excl),
+                    dhcpLeaseTimeSecs, linkMtu);
+        }
+    }
+
+    @NonNull
+    static IpPrefix makeIpPrefix(@NonNull LinkAddress addr) {
+        return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
+    }
+}
diff --git a/services/net/java/android/net/util/FdEventsReader.java b/services/net/java/android/net/util/FdEventsReader.java
new file mode 100644
index 0000000..575444f
--- /dev/null
+++ b/services/net/java/android/net/util/FdEventsReader.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.util;
+
+import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
+import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+
+import libcore.io.IoUtils;
+
+import java.io.FileDescriptor;
+
+
+/**
+ * This class encapsulates the mechanics of registering a file descriptor
+ * with a thread's Looper and handling read events (and errors).
+ *
+ * Subclasses MUST implement createFd() and SHOULD override handlePacket(). They MAY override
+ * onStop() and onStart().
+ *
+ * Subclasses can expect a call life-cycle like the following:
+ *
+ *     [1] when a client calls start(), createFd() is called, followed by the onStart() hook if all
+ *         goes well. Implementations may override onStart() for additional initialization.
+ *
+ *     [2] yield, waiting for read event or error notification:
+ *
+ *             [a] readPacket() && handlePacket()
+ *
+ *             [b] if (no error):
+ *                     goto 2
+ *                 else:
+ *                     goto 3
+ *
+ *     [3] when a client calls stop(), the onStop() hook is called (unless already stopped or never
+ *         started). Implementations may override onStop() for additional cleanup.
+ *
+ * The packet receive buffer is recycled on every read call, so subclasses
+ * should make any copies they would like inside their handlePacket()
+ * implementation.
+ *
+ * All public methods MUST only be called from the same thread with which
+ * the Handler constructor argument is associated.
+ *
+ * @hide
+ */
+public abstract class FdEventsReader<BufferType> {
+    private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
+    private static final int UNREGISTER_THIS_FD = 0;
+
+    @NonNull
+    private final Handler mHandler;
+    @NonNull
+    private final MessageQueue mQueue;
+    @NonNull
+    private final BufferType mBuffer;
+    @Nullable
+    private FileDescriptor mFd;
+    private long mPacketsReceived;
+
+    protected static void closeFd(FileDescriptor fd) {
+        IoUtils.closeQuietly(fd);
+    }
+
+    protected FdEventsReader(@NonNull Handler h, @NonNull BufferType buffer) {
+        mHandler = h;
+        mQueue = mHandler.getLooper().getQueue();
+        mBuffer = buffer;
+    }
+
+    public final void start() {
+        if (onCorrectThread()) {
+            createAndRegisterFd();
+        } else {
+            mHandler.post(() -> {
+                logError("start() called from off-thread", null);
+                createAndRegisterFd();
+            });
+        }
+    }
+
+    public final void stop() {
+        if (onCorrectThread()) {
+            unregisterAndDestroyFd();
+        } else {
+            mHandler.post(() -> {
+                logError("stop() called from off-thread", null);
+                unregisterAndDestroyFd();
+            });
+        }
+    }
+
+    @NonNull
+    public Handler getHandler() { return mHandler; }
+
+    protected abstract int recvBufSize(@NonNull BufferType buffer);
+
+    public int recvBufSize() { return recvBufSize(mBuffer); }
+
+    /**
+     * Get the number of successful calls to {@link #readPacket(FileDescriptor, Object)}.
+     *
+     * <p>A call was successful if {@link #readPacket(FileDescriptor, Object)} returned a value > 0.
+     */
+    public final long numPacketsReceived() { return mPacketsReceived; }
+
+    /**
+     * Subclasses MUST create the listening socket here, including setting
+     * all desired socket options, interface or address/port binding, etc.
+     */
+    @Nullable
+    protected abstract FileDescriptor createFd();
+
+    /**
+     * Implementations MUST return the bytes read or throw an Exception.
+     *
+     * <p>The caller may throw a {@link ErrnoException} with {@link OsConstants#EAGAIN} or
+     * {@link OsConstants#EINTR}, in which case {@link FdEventsReader} will ignore the buffer
+     * contents and respectively wait for further input or retry the read immediately. For all other
+     * exceptions, the {@link FdEventsReader} will be stopped with no more interactions with this
+     * method.
+     */
+    protected abstract int readPacket(@NonNull FileDescriptor fd, @NonNull BufferType buffer)
+            throws Exception;
+
+    /**
+     * Called by the main loop for every packet.  Any desired copies of
+     * |recvbuf| should be made in here, as the underlying byte array is
+     * reused across all reads.
+     */
+    protected void handlePacket(@NonNull BufferType recvbuf, int length) {}
+
+    /**
+     * Called by the main loop to log errors.  In some cases |e| may be null.
+     */
+    protected void logError(@NonNull String msg, @Nullable Exception e) {}
+
+    /**
+     * Called by start(), if successful, just prior to returning.
+     */
+    protected void onStart() {}
+
+    /**
+     * Called by stop() just prior to returning.
+     */
+    protected void onStop() {}
+
+    private void createAndRegisterFd() {
+        if (mFd != null) return;
+
+        try {
+            mFd = createFd();
+            if (mFd != null) {
+                // Force the socket to be non-blocking.
+                IoUtils.setBlocking(mFd, false);
+            }
+        } catch (Exception e) {
+            logError("Failed to create socket: ", e);
+            closeFd(mFd);
+            mFd = null;
+        }
+
+        if (mFd == null) return;
+
+        mQueue.addOnFileDescriptorEventListener(
+                mFd,
+                FD_EVENTS,
+                (fd, events) -> {
+                    // Always call handleInput() so read/recvfrom are given
+                    // a proper chance to encounter a meaningful errno and
+                    // perhaps log a useful error message.
+                    if (!isRunning() || !handleInput()) {
+                        unregisterAndDestroyFd();
+                        return UNREGISTER_THIS_FD;
+                    }
+                    return FD_EVENTS;
+                });
+        onStart();
+    }
+
+    private boolean isRunning() { return (mFd != null) && mFd.valid(); }
+
+    // Keep trying to read until we get EAGAIN/EWOULDBLOCK or some fatal error.
+    private boolean handleInput() {
+        while (isRunning()) {
+            final int bytesRead;
+
+            try {
+                bytesRead = readPacket(mFd, mBuffer);
+                if (bytesRead < 1) {
+                    if (isRunning()) logError("Socket closed, exiting", null);
+                    break;
+                }
+                mPacketsReceived++;
+            } catch (ErrnoException e) {
+                if (e.errno == OsConstants.EAGAIN) {
+                    // We've read everything there is to read this time around.
+                    return true;
+                } else if (e.errno == OsConstants.EINTR) {
+                    continue;
+                } else {
+                    if (isRunning()) logError("readPacket error: ", e);
+                    break;
+                }
+            } catch (Exception e) {
+                if (isRunning()) logError("readPacket error: ", e);
+                break;
+            }
+
+            try {
+                handlePacket(mBuffer, bytesRead);
+            } catch (Exception e) {
+                logError("handlePacket error: ", e);
+                break;
+            }
+        }
+
+        return false;
+    }
+
+    private void unregisterAndDestroyFd() {
+        if (mFd == null) return;
+
+        mQueue.removeOnFileDescriptorEventListener(mFd);
+        closeFd(mFd);
+        mFd = null;
+        onStop();
+    }
+
+    private boolean onCorrectThread() {
+        return (mHandler.getLooper() == Looper.myLooper());
+    }
+}
diff --git a/services/net/java/android/net/util/NetworkConstants.java b/services/net/java/android/net/util/NetworkConstants.java
index de04fd0..3defe56 100644
--- a/services/net/java/android/net/util/NetworkConstants.java
+++ b/services/net/java/android/net/util/NetworkConstants.java
@@ -77,10 +77,12 @@
     /**
      * IPv4 constants.
      *
-     * See als:
+     * See also:
      *     - https://tools.ietf.org/html/rfc791
      */
     public static final int IPV4_HEADER_MIN_LEN = 20;
+    public static final int IPV4_MIN_MTU = 68;
+    public static final int IPV4_MAX_MTU = 65_535;
     public static final int IPV4_IHL_MASK = 0xf;
     public static final int IPV4_FLAGS_OFFSET = 6;
     public static final int IPV4_FRAGMENT_MASK = 0x1fff;
diff --git a/services/net/java/android/net/util/PacketReader.java b/services/net/java/android/net/util/PacketReader.java
index 10da2a5..4aec6b6 100644
--- a/services/net/java/android/net/util/PacketReader.java
+++ b/services/net/java/android/net/util/PacketReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,236 +16,46 @@
 
 package android.net.util;
 
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
+import static java.lang.Math.max;
 
-import android.annotation.Nullable;
 import android.os.Handler;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.os.MessageQueue.OnFileDescriptorEventListener;
-import android.system.ErrnoException;
 import android.system.Os;
-import android.system.OsConstants;
-
-import libcore.io.IoUtils;
 
 import java.io.FileDescriptor;
-import java.io.IOException;
-
 
 /**
- * This class encapsulates the mechanics of registering a file descriptor
- * with a thread's Looper and handling read events (and errors).
- *
- * Subclasses MUST implement createFd() and SHOULD override handlePacket().
-
- * Subclasses can expect a call life-cycle like the following:
- *
- *     [1] start() calls createFd() and (if all goes well) onStart()
- *
- *     [2] yield, waiting for read event or error notification:
- *
- *             [a] readPacket() && handlePacket()
- *
- *             [b] if (no error):
- *                     goto 2
- *                 else:
- *                     goto 3
- *
- *     [3] stop() calls onStop() if not previously stopped
- *
- * The packet receive buffer is recycled on every read call, so subclasses
- * should make any copies they would like inside their handlePacket()
- * implementation.
- *
- * All public methods MUST only be called from the same thread with which
- * the Handler constructor argument is associated.
+ * Specialization of {@link FdEventsReader} that reads packets into a byte array.
  *
  * TODO: rename this class to something more correctly descriptive (something
  * like [or less horrible than] FdReadEventsHandler?).
  *
  * @hide
  */
-public abstract class PacketReader {
-    private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
-    private static final int UNREGISTER_THIS_FD = 0;
+public abstract class PacketReader extends FdEventsReader<byte[]> {
 
     public static final int DEFAULT_RECV_BUF_SIZE = 2 * 1024;
 
-    private final Handler mHandler;
-    private final MessageQueue mQueue;
-    private final byte[] mPacket;
-    private FileDescriptor mFd;
-    private long mPacketsReceived;
-
-    protected static void closeFd(FileDescriptor fd) {
-        IoUtils.closeQuietly(fd);
-    }
-
     protected PacketReader(Handler h) {
         this(h, DEFAULT_RECV_BUF_SIZE);
     }
 
-    protected PacketReader(Handler h, int recvbufsize) {
-        mHandler = h;
-        mQueue = mHandler.getLooper().getQueue();
-        mPacket = new byte[Math.max(recvbufsize, DEFAULT_RECV_BUF_SIZE)];
+    protected PacketReader(Handler h, int recvBufSize) {
+        super(h, new byte[max(recvBufSize, DEFAULT_RECV_BUF_SIZE)]);
     }
 
-    public final void start() {
-        if (onCorrectThread()) {
-            createAndRegisterFd();
-        } else {
-            mHandler.post(() -> {
-                logError("start() called from off-thread", null);
-                createAndRegisterFd();
-            });
-        }
+    @Override
+    protected final int recvBufSize(byte[] buffer) {
+        return buffer.length;
     }
 
-    public final void stop() {
-        if (onCorrectThread()) {
-            unregisterAndDestroyFd();
-        } else {
-            mHandler.post(() -> {
-                logError("stop() called from off-thread", null);
-                unregisterAndDestroyFd();
-            });
-        }
-    }
-
-    public Handler getHandler() { return mHandler; }
-
-    public final int recvBufSize() { return mPacket.length; }
-
-    public final long numPacketsReceived() { return mPacketsReceived; }
-
-    /**
-     * Subclasses MUST create the listening socket here, including setting
-     * all desired socket options, interface or address/port binding, etc.
-     */
-    protected abstract FileDescriptor createFd();
-
     /**
      * Subclasses MAY override this to change the default read() implementation
      * in favour of, say, recvfrom().
      *
      * Implementations MUST return the bytes read or throw an Exception.
      */
+    @Override
     protected int readPacket(FileDescriptor fd, byte[] packetBuffer) throws Exception {
         return Os.read(fd, packetBuffer, 0, packetBuffer.length);
     }
-
-    /**
-     * Called by the main loop for every packet.  Any desired copies of
-     * |recvbuf| should be made in here, as the underlying byte array is
-     * reused across all reads.
-     */
-    protected void handlePacket(byte[] recvbuf, int length) {}
-
-    /**
-     * Called by the main loop to log errors.  In some cases |e| may be null.
-     */
-    protected void logError(String msg, Exception e) {}
-
-    /**
-     * Called by start(), if successful, just prior to returning.
-     */
-    protected void onStart() {}
-
-    /**
-     * Called by stop() just prior to returning.
-     */
-    protected void onStop() {}
-
-    private void createAndRegisterFd() {
-        if (mFd != null) return;
-
-        try {
-            mFd = createFd();
-            if (mFd != null) {
-                // Force the socket to be non-blocking.
-                IoUtils.setBlocking(mFd, false);
-            }
-        } catch (Exception e) {
-            logError("Failed to create socket: ", e);
-            closeFd(mFd);
-            mFd = null;
-            return;
-        }
-
-        if (mFd == null) return;
-
-        mQueue.addOnFileDescriptorEventListener(
-                mFd,
-                FD_EVENTS,
-                new OnFileDescriptorEventListener() {
-                    @Override
-                    public int onFileDescriptorEvents(FileDescriptor fd, int events) {
-                        // Always call handleInput() so read/recvfrom are given
-                        // a proper chance to encounter a meaningful errno and
-                        // perhaps log a useful error message.
-                        if (!isRunning() || !handleInput()) {
-                            unregisterAndDestroyFd();
-                            return UNREGISTER_THIS_FD;
-                        }
-                        return FD_EVENTS;
-                    }
-                });
-        onStart();
-    }
-
-    private boolean isRunning() { return (mFd != null) && mFd.valid(); }
-
-    // Keep trying to read until we get EAGAIN/EWOULDBLOCK or some fatal error.
-    private boolean handleInput() {
-        while (isRunning()) {
-            final int bytesRead;
-
-            try {
-                bytesRead = readPacket(mFd, mPacket);
-                if (bytesRead < 1) {
-                    if (isRunning()) logError("Socket closed, exiting", null);
-                    break;
-                }
-                mPacketsReceived++;
-            } catch (ErrnoException e) {
-                if (e.errno == OsConstants.EAGAIN) {
-                    // We've read everything there is to read this time around.
-                    return true;
-                } else if (e.errno == OsConstants.EINTR) {
-                    continue;
-                } else {
-                    if (isRunning()) logError("readPacket error: ", e);
-                    break;
-                }
-            } catch (Exception e) {
-                if (isRunning()) logError("readPacket error: ", e);
-                break;
-            }
-
-            try {
-                handlePacket(mPacket, bytesRead);
-            } catch (Exception e) {
-                logError("handlePacket error: ", e);
-                break;
-            }
-        }
-
-        return false;
-    }
-
-    private void unregisterAndDestroyFd() {
-        if (mFd == null) return;
-
-        mQueue.removeOnFileDescriptorEventListener(mFd);
-        closeFd(mFd);
-        mFd = null;
-        onStop();
-    }
-
-    private boolean onCorrectThread() {
-        return (mHandler.getLooper() == Looper.myLooper());
-    }
 }
diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java
index bbd3d13..f7bf393 100644
--- a/services/net/java/android/net/util/SharedLog.java
+++ b/services/net/java/android/net/util/SharedLog.java
@@ -16,6 +16,7 @@
 
 package android.net.util;
 
+import android.annotation.NonNull;
 import android.text.TextUtils;
 import android.util.LocalLog;
 import android.util.Log;
@@ -90,6 +91,13 @@
         Log.e(mTag, record(Category.ERROR, msg));
     }
 
+    /**
+     * Log an error due to an exception, with the exception stacktrace.
+     */
+    public void e(@NonNull String msg, @NonNull Throwable e) {
+        Log.e(mTag, record(Category.ERROR, msg + ": " + e.getMessage()), e);
+    }
+
     public void i(String msg) {
         Log.i(mTag, record(Category.NONE, msg));
     }
diff --git a/tests/net/java/android/net/NetworkUtilsTest.java b/tests/net/java/android/net/NetworkUtilsTest.java
index 2b172da..3452819 100644
--- a/tests/net/java/android/net/NetworkUtilsTest.java
+++ b/tests/net/java/android/net/NetworkUtilsTest.java
@@ -24,6 +24,8 @@
 import static android.net.NetworkUtils.netmaskToPrefixLength;
 import static android.net.NetworkUtils.prefixLengthToV4NetmaskIntHTH;
 import static android.net.NetworkUtils.prefixLengthToV4NetmaskIntHTL;
+import static android.net.NetworkUtils.getBroadcastAddress;
+import static android.net.NetworkUtils.getPrefixMaskAsInet4Address;
 
 import static junit.framework.Assert.assertEquals;
 
@@ -125,7 +127,6 @@
         assertInvalidNetworkMask(IPv4Address("255.255.0.255"));
     }
 
-
     @Test
     public void testPrefixLengthToV4NetmaskIntHTL() {
         assertEquals(0, prefixLengthToV4NetmaskIntHTL(0));
@@ -266,4 +267,44 @@
         assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536),
                 NetworkUtils.routedIPv6AddressCount(set));
     }
+
+    @Test
+    public void testGetPrefixMaskAsAddress() {
+        assertEquals("255.255.240.0", getPrefixMaskAsInet4Address(20).getHostAddress());
+        assertEquals("255.0.0.0", getPrefixMaskAsInet4Address(8).getHostAddress());
+        assertEquals("0.0.0.0", getPrefixMaskAsInet4Address(0).getHostAddress());
+        assertEquals("255.255.255.255", getPrefixMaskAsInet4Address(32).getHostAddress());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetPrefixMaskAsAddress_PrefixTooLarge() {
+        getPrefixMaskAsInet4Address(33);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetPrefixMaskAsAddress_NegativePrefix() {
+        getPrefixMaskAsInet4Address(-1);
+    }
+
+    @Test
+    public void testGetBroadcastAddress() {
+        assertEquals("192.168.15.255",
+                getBroadcastAddress(IPv4Address("192.168.0.123"), 20).getHostAddress());
+        assertEquals("192.255.255.255",
+                getBroadcastAddress(IPv4Address("192.168.0.123"), 8).getHostAddress());
+        assertEquals("192.168.0.123",
+                getBroadcastAddress(IPv4Address("192.168.0.123"), 32).getHostAddress());
+        assertEquals("255.255.255.255",
+                getBroadcastAddress(IPv4Address("192.168.0.123"), 0).getHostAddress());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetBroadcastAddress_PrefixTooLarge() {
+        getBroadcastAddress(IPv4Address("192.168.0.123"), 33);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetBroadcastAddress_NegativePrefix() {
+        getBroadcastAddress(IPv4Address("192.168.0.123"), -1);
+    }
 }
diff --git a/tests/net/java/android/net/dhcp/DhcpLeaseRepositoryTest.java b/tests/net/java/android/net/dhcp/DhcpLeaseRepositoryTest.java
new file mode 100644
index 0000000..edadd6e
--- /dev/null
+++ b/tests/net/java/android/net/dhcp/DhcpLeaseRepositoryTest.java
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.dhcp;
+
+import static android.net.dhcp.DhcpLease.HOSTNAME_NONE;
+import static android.net.dhcp.DhcpLeaseRepository.CLIENTID_UNSPEC;
+import static android.net.dhcp.DhcpLeaseRepository.INETADDR_UNSPEC;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.when;
+
+import static java.lang.String.format;
+import static java.net.InetAddress.parseNumericAddress;
+
+import android.annotation.NonNull;
+import android.net.IpPrefix;
+import android.net.MacAddress;
+import android.net.dhcp.DhcpLeaseRepository.Clock;
+import android.net.util.SharedLog;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.net.Inet4Address;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DhcpLeaseRepositoryTest {
+    private static final Inet4Address INET4_ANY = (Inet4Address) Inet4Address.ANY;
+    private static final Inet4Address TEST_DEF_ROUTER = parseAddr4("192.168.42.247");
+    private static final Inet4Address TEST_SERVER_ADDR = parseAddr4("192.168.42.241");
+    private static final Inet4Address TEST_RESERVED_ADDR = parseAddr4("192.168.42.243");
+    private static final MacAddress TEST_MAC_1 = MacAddress.fromBytes(
+            new byte[] { 5, 4, 3, 2, 1, 0 });
+    private static final MacAddress TEST_MAC_2 = MacAddress.fromBytes(
+            new byte[] { 0, 1, 2, 3, 4, 5 });
+    private static final MacAddress TEST_MAC_3 = MacAddress.fromBytes(
+            new byte[] { 0, 1, 2, 3, 4, 6 });
+    private static final Inet4Address TEST_INETADDR_1 = parseAddr4("192.168.42.248");
+    private static final Inet4Address TEST_INETADDR_2 = parseAddr4("192.168.42.249");
+    private static final String TEST_HOSTNAME_1 = "hostname1";
+    private static final String TEST_HOSTNAME_2 = "hostname2";
+    private static final IpPrefix TEST_IP_PREFIX = new IpPrefix(TEST_SERVER_ADDR, 22);
+    private static final long TEST_TIME = 100L;
+    private static final int TEST_LEASE_TIME_MS = 3_600_000;
+    private static final Set<Inet4Address> TEST_EXCL_SET =
+            Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+                TEST_SERVER_ADDR, TEST_DEF_ROUTER, TEST_RESERVED_ADDR)));
+
+    @NonNull
+    private SharedLog mLog;
+    @NonNull @Mock
+    private Clock mClock;
+    @NonNull
+    private DhcpLeaseRepository mRepo;
+
+    private static Inet4Address parseAddr4(String inet4Addr) {
+        return (Inet4Address) parseNumericAddress(inet4Addr);
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mLog = new SharedLog("DhcpLeaseRepositoryTest");
+        when(mClock.elapsedRealtime()).thenReturn(TEST_TIME);
+        mRepo = new DhcpLeaseRepository(
+                TEST_IP_PREFIX, TEST_EXCL_SET, TEST_LEASE_TIME_MS, mLog, mClock);
+    }
+
+    /**
+     * Request a number of addresses through offer/request. Useful to test address exhaustion.
+     * @param nAddr Number of addresses to request.
+     */
+    private void requestAddresses(byte nAddr) throws Exception {
+        final HashSet<Inet4Address> addrs = new HashSet<>();
+        byte[] hwAddrBytes = new byte[] { 8, 4, 3, 2, 1, 0 };
+        for (byte i = 0; i < nAddr; i++) {
+            hwAddrBytes[5] = i;
+            MacAddress newMac = MacAddress.fromBytes(hwAddrBytes);
+            final String hostname = "host_" + i;
+            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, newMac,
+                    INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, hostname);
+
+            assertNotNull(lease);
+            assertEquals(newMac, lease.getHwAddr());
+            assertEquals(hostname, lease.getHostname());
+            assertTrue(format("Duplicate address allocated: %s in %s", lease.getNetAddr(), addrs),
+                    addrs.add(lease.getNetAddr()));
+
+            mRepo.requestLease(null, newMac, null, lease.getNetAddr(), true, hostname);
+        }
+    }
+
+    @Test
+    public void testAddressExhaustion() throws Exception {
+        // Use a /28 to quickly run out of addresses
+        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
+
+        // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
+        requestAddresses((byte)11);
+
+        try {
+            mRepo.getOffer(null, TEST_MAC_2,
+                    null /* relayAddr */, null /* reqAddr */, HOSTNAME_NONE);
+            fail("Should be out of addresses");
+        } catch (DhcpLeaseRepository.OutOfAddressesException e) {
+            // Expected
+        }
+    }
+
+    @Test
+    public void testUpdateParams_LeaseCleanup() throws Exception {
+        // Inside /28:
+        final Inet4Address reqAddrIn28 = parseAddr4("192.168.42.242");
+        final Inet4Address declinedAddrIn28 = parseAddr4("192.168.42.245");
+
+        // Inside /28, but not available there (first address of the range)
+        final Inet4Address declinedFirstAddrIn28 = parseAddr4("192.168.42.240");
+
+        final DhcpLease reqAddrIn28Lease = mRepo.requestLease(
+                CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, reqAddrIn28, false, HOSTNAME_NONE);
+        mRepo.markLeaseDeclined(declinedAddrIn28);
+        mRepo.markLeaseDeclined(declinedFirstAddrIn28);
+
+        // Inside /22, but outside /28:
+        final Inet4Address reqAddrIn22 = parseAddr4("192.168.42.3");
+        final Inet4Address declinedAddrIn22 = parseAddr4("192.168.42.4");
+
+        final DhcpLease reqAddrIn22Lease = mRepo.requestLease(
+                CLIENTID_UNSPEC, TEST_MAC_3, INET4_ANY, reqAddrIn22, false, HOSTNAME_NONE);
+        mRepo.markLeaseDeclined(declinedAddrIn22);
+
+        // Address that will be reserved in the updateParams call below
+        final Inet4Address reservedAddr = parseAddr4("192.168.42.244");
+        final DhcpLease reservedAddrLease = mRepo.requestLease(
+                CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY, reservedAddr, false, HOSTNAME_NONE);
+
+        // Update from /22 to /28 and add another reserved address
+        Set<Inet4Address> newReserved = new HashSet<>(TEST_EXCL_SET);
+        newReserved.add(reservedAddr);
+        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), newReserved, TEST_LEASE_TIME_MS);
+
+        assertHasLease(reqAddrIn28Lease);
+        assertDeclined(declinedAddrIn28);
+
+        assertNotDeclined(declinedFirstAddrIn28);
+
+        assertNoLease(reqAddrIn22Lease);
+        assertNotDeclined(declinedAddrIn22);
+
+        assertNoLease(reservedAddrLease);
+    }
+
+    @Test
+    public void testGetOffer_StableAddress() throws Exception {
+        for (final MacAddress macAddr : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
+            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
+                    INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
+
+            // Same lease is offered twice
+            final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
+                    INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
+            assertEquals(lease, newLease);
+        }
+    }
+
+    @Test
+    public void testUpdateParams_UsesNewPrefix() throws Exception {
+        final IpPrefix newPrefix = new IpPrefix(parseAddr4("192.168.123.0"), 24);
+        mRepo.updateParams(newPrefix, TEST_EXCL_SET, TEST_LEASE_TIME_MS);
+
+        DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
+                INETADDR_UNSPEC, INETADDR_UNSPEC, HOSTNAME_NONE);
+        assertTrue(newPrefix.contains(lease.getNetAddr()));
+    }
+
+    @Test
+    public void testGetOffer_ExistingLease() throws Exception {
+        mRepo.requestLease(
+                CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, TEST_INETADDR_1, false, TEST_HOSTNAME_1);
+
+        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
+                INETADDR_UNSPEC, INETADDR_UNSPEC, HOSTNAME_NONE);
+        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
+        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
+    }
+
+    @Test
+    public void testGetOffer_ClientIdHasExistingLease() throws Exception {
+        final byte[] clientId = new byte[] { 1, 2 };
+        mRepo.requestLease(clientId, TEST_MAC_1, INET4_ANY, TEST_INETADDR_1, false,
+                TEST_HOSTNAME_1);
+
+        // Different MAC, but same clientId
+        DhcpLease offer = mRepo.getOffer(clientId, TEST_MAC_2,
+                INETADDR_UNSPEC, INETADDR_UNSPEC, HOSTNAME_NONE);
+        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
+        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
+    }
+
+    @Test
+    public void testGetOffer_DifferentClientId() throws Exception {
+        final byte[] clientId1 = new byte[] { 1, 2 };
+        final byte[] clientId2 = new byte[] { 3, 4 };
+        mRepo.requestLease(clientId1, TEST_MAC_1, INET4_ANY, TEST_INETADDR_1, false,
+                TEST_HOSTNAME_1);
+
+        // Same MAC, different client ID
+        DhcpLease offer = mRepo.getOffer(clientId2, TEST_MAC_1,
+                INETADDR_UNSPEC, INETADDR_UNSPEC, HOSTNAME_NONE);
+        // Obtains a different address
+        assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
+        assertEquals(HOSTNAME_NONE, offer.getHostname());
+        assertEquals(TEST_MAC_1, offer.getHwAddr());
+    }
+
+    @Test
+    public void testGetOffer_RequestedAddress() throws Exception {
+        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_INETADDR_1, TEST_HOSTNAME_1);
+        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
+        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
+    }
+
+    @Test
+    public void testGetOffer_RequestedAddressInUse() throws Exception {
+        mRepo.requestLease(
+                CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, TEST_INETADDR_1, false, HOSTNAME_NONE);
+        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY,
+                TEST_INETADDR_1, HOSTNAME_NONE);
+        assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
+    }
+
+    @Test
+    public void testGetOffer_RequestedAddressReserved() throws Exception {
+        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_RESERVED_ADDR, HOSTNAME_NONE);
+        assertNotEquals(TEST_RESERVED_ADDR, offer.getNetAddr());
+    }
+
+    @Test
+    public void testGetOffer_RequestedAddressInvalid() throws Exception {
+        final Inet4Address invalidAddr = parseAddr4("192.168.42.0");
+        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                invalidAddr, HOSTNAME_NONE);
+        assertNotEquals(invalidAddr, offer.getNetAddr());
+    }
+
+    @Test
+    public void testGetOffer_RequestedAddressOutsideSubnet() throws Exception {
+        final Inet4Address invalidAddr = parseAddr4("192.168.254.2");
+        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                invalidAddr, HOSTNAME_NONE);
+        assertNotEquals(invalidAddr, offer.getNetAddr());
+    }
+
+    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
+    public void testGetOffer_RelayInInvalidSubnet() throws Exception {
+        mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
+                parseAddr4("192.168.254.2") /* relayAddr */, INETADDR_UNSPEC, HOSTNAME_NONE);
+    }
+
+    @Test
+    public void testRequestLease_SelectingTwice() throws Exception {
+        DhcpLease lease1 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_INETADDR_1, true /* sidSet */, TEST_HOSTNAME_1);
+
+        // Second request from same client for a different address
+        DhcpLease lease2 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_INETADDR_2, true /* sidSet */, TEST_HOSTNAME_2);
+
+        assertEquals(TEST_INETADDR_1, lease1.getNetAddr());
+        assertEquals(TEST_HOSTNAME_1, lease1.getHostname());
+
+        assertEquals(TEST_INETADDR_2, lease2.getNetAddr());
+        assertEquals(TEST_HOSTNAME_2, lease2.getHostname());
+
+        // First address freed when client requested a different one: another client can request it
+        DhcpLease lease3 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY,
+                TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
+        assertEquals(TEST_INETADDR_1, lease3.getNetAddr());
+    }
+
+    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
+    public void testRequestLease_SelectingInvalid() throws Exception {
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                parseAddr4("192.168.254.5"), true /* sidSet */, HOSTNAME_NONE);
+    }
+
+    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
+    public void testRequestLease_SelectingInUse() throws Exception {
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY,
+                TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
+    }
+
+    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
+    public void testRequestLease_SelectingReserved() throws Exception {
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_RESERVED_ADDR, true /* sidSet */, HOSTNAME_NONE);
+    }
+
+    @Test
+    public void testRequestLease_InitReboot() throws Exception {
+        // Request address once
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
+
+        final long newTime = TEST_TIME + 100;
+        when(mClock.elapsedRealtime()).thenReturn(newTime);
+
+        // init-reboot (sidSet == false): verify configuration
+        DhcpLease lease = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_INETADDR_1, false, HOSTNAME_NONE);
+        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
+        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
+    }
+
+    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
+    public void testRequestLease_InitRebootWrongAddr() throws Exception {
+        // Request address once
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
+        // init-reboot with different requested address
+        mRepo.requestLease(
+                CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, TEST_INETADDR_2, false, HOSTNAME_NONE);
+    }
+
+    @Test
+    public void testRequestLease_InitRebootUnknownAddr() throws Exception {
+        // init-reboot with unknown requested address
+        DhcpLease lease = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_INETADDR_2, false, HOSTNAME_NONE);
+        // RFC2131 says we should not reply to accommodate other servers, but since we are
+        // authoritative we allow creating the lease to avoid issues with lost lease DB (same as
+        // dnsmasq behavior)
+        assertEquals(TEST_INETADDR_2, lease.getNetAddr());
+    }
+
+    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
+    public void testRequestLease_InitRebootWrongSubnet() throws Exception {
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                parseAddr4("192.168.254.2"), false /* sidSet */, HOSTNAME_NONE);
+    }
+
+    @Test
+    public void testRequestLease_Renewing() throws Exception {
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1,
+                INET4_ANY /* clientAddr */, TEST_INETADDR_1 /* reqAddr */, true, HOSTNAME_NONE);
+
+        final long newTime = TEST_TIME + 100;
+        when(mClock.elapsedRealtime()).thenReturn(newTime);
+
+        // Renewing: clientAddr filled in, no reqAddr
+        DhcpLease lease = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1,
+                TEST_INETADDR_1 /* clientAddr */, INETADDR_UNSPEC /* reqAddr */, false,
+                HOSTNAME_NONE);
+
+        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
+        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
+    }
+
+    @Test
+    public void testRequestLease_RenewingUnknownAddr() throws Exception {
+        final long newTime = TEST_TIME + 100;
+        when(mClock.elapsedRealtime()).thenReturn(newTime);
+        DhcpLease lease = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1,
+                TEST_INETADDR_1 /* clientAddr */, INETADDR_UNSPEC /* reqAddr */, false,
+                HOSTNAME_NONE);
+        // Allows renewing an unknown address if available
+        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
+        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
+    }
+
+    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
+    public void testRequestLease_RenewingAddrInUse() throws Exception {
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2,
+                INET4_ANY /* clientAddr */, TEST_INETADDR_1 /* reqAddr */, true, HOSTNAME_NONE);
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1,
+                TEST_INETADDR_1 /* clientAddr */, INETADDR_UNSPEC /* reqAddr */, false,
+                HOSTNAME_NONE);
+    }
+
+    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
+    public void testRequestLease_RenewingInvalidAddr() throws Exception {
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, parseAddr4("192.168.254.2") /* clientAddr */,
+                INETADDR_UNSPEC /* reqAddr */, false, HOSTNAME_NONE);
+    }
+
+    @Test
+    public void testReleaseLease() throws Exception {
+        DhcpLease lease1 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY,
+                TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
+
+        assertHasLease(lease1);
+        assertTrue(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
+        assertNoLease(lease1);
+
+        DhcpLease lease2 = mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY,
+                TEST_INETADDR_1, true /* sidSet */, HOSTNAME_NONE);
+
+        assertEquals(TEST_INETADDR_1, lease2.getNetAddr());
+    }
+
+    @Test
+    public void testReleaseLease_UnknownLease() {
+        assertFalse(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
+    }
+
+    @Test
+    public void testReleaseLease_StableOffer() throws Exception {
+        for (MacAddress mac : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
+            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
+                    INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
+            mRepo.requestLease(
+                    CLIENTID_UNSPEC, mac, INET4_ANY, lease.getNetAddr(), true,
+                    HOSTNAME_NONE);
+            mRepo.releaseLease(CLIENTID_UNSPEC, mac, lease.getNetAddr());
+
+            // Same lease is offered after it was released
+            final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
+                    INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
+            assertEquals(lease.getNetAddr(), newLease.getNetAddr());
+        }
+    }
+
+    @Test
+    public void testMarkLeaseDeclined() throws Exception {
+        final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
+                INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
+
+        mRepo.markLeaseDeclined(lease.getNetAddr());
+
+        // Same lease is not offered again
+        final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
+                INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
+        assertNotEquals(lease.getNetAddr(), newLease.getNetAddr());
+    }
+
+    @Test
+    public void testMarkLeaseDeclined_UsedIfOutOfAddresses() throws Exception {
+        // Use a /28 to quickly run out of addresses
+        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
+
+        mRepo.markLeaseDeclined(TEST_INETADDR_1);
+        mRepo.markLeaseDeclined(TEST_INETADDR_2);
+
+        // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
+        requestAddresses((byte)9);
+
+        // Last 2 addresses: addresses marked declined should be used
+        final DhcpLease firstLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
+                INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_1);
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, INET4_ANY, firstLease.getNetAddr(), true,
+                HOSTNAME_NONE);
+
+        final DhcpLease secondLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2,
+                INETADDR_UNSPEC /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_2);
+        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_2, INET4_ANY, secondLease.getNetAddr(), true,
+                HOSTNAME_NONE);
+
+        // Now out of addresses
+        try {
+            mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_3, INETADDR_UNSPEC /* relayAddr */,
+                    INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
+            fail("Repository should be out of addresses and throw");
+        } catch (DhcpLeaseRepository.OutOfAddressesException e) { /* expected */ }
+
+        assertEquals(TEST_INETADDR_1, firstLease.getNetAddr());
+        assertEquals(TEST_HOSTNAME_1, firstLease.getHostname());
+        assertEquals(TEST_INETADDR_2, secondLease.getNetAddr());
+        assertEquals(TEST_HOSTNAME_2, secondLease.getHostname());
+    }
+
+    private void assertNoLease(DhcpLease lease) {
+        assertFalse("Leases contain " + lease, mRepo.getCommittedLeases().contains(lease));
+    }
+
+    private void assertHasLease(DhcpLease lease) {
+        assertTrue("Leases do not contain " + lease, mRepo.getCommittedLeases().contains(lease));
+    }
+
+    private void assertNotDeclined(Inet4Address addr) {
+        assertFalse("Address is declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
+    }
+
+    private void assertDeclined(Inet4Address addr) {
+        assertTrue("Address is not declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
+    }
+}
diff --git a/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java b/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java
new file mode 100644
index 0000000..dfa09a9
--- /dev/null
+++ b/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.dhcp;
+
+import static android.net.dhcp.DhcpServingParams.MTU_UNSET;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static java.net.InetAddress.parseNumericAddress;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.LinkAddress;
+import android.net.dhcp.DhcpServingParams.InvalidParameterException;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.Inet4Address;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DhcpServingParamsTest {
+    @NonNull
+    private DhcpServingParams.Builder mBuilder;
+
+    private static final Set<Inet4Address> TEST_DEFAULT_ROUTERS = new HashSet<>(
+            Arrays.asList(parseAddr("192.168.0.123"), parseAddr("192.168.0.124")));
+    private static final long TEST_LEASE_TIME_SECS = 3600L;
+    private static final Set<Inet4Address> TEST_DNS_SERVERS = new HashSet<>(
+            Arrays.asList(parseAddr("192.168.0.126"), parseAddr("192.168.0.127")));
+    private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
+    private static final LinkAddress TEST_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
+    private static final int TEST_MTU = 1500;
+    private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>(
+            Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201")));
+
+    @Before
+    public void setUp() {
+        mBuilder = new DhcpServingParams.Builder()
+                .setDefaultRouters(TEST_DEFAULT_ROUTERS)
+                .setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS)
+                .setDnsServers(TEST_DNS_SERVERS)
+                .setServerAddr(TEST_LINKADDR)
+                .setLinkMtu(TEST_MTU)
+                .setExcludedAddrs(TEST_EXCLUDED_ADDRS);
+    }
+
+    @Test
+    public void testBuild_Immutable() throws InvalidParameterException {
+        final Set<Inet4Address> routers = new HashSet<>(TEST_DEFAULT_ROUTERS);
+        final Set<Inet4Address> dnsServers = new HashSet<>(TEST_DNS_SERVERS);
+        final Set<Inet4Address> excludedAddrs = new HashSet<>(TEST_EXCLUDED_ADDRS);
+
+        final DhcpServingParams params = mBuilder
+                .setDefaultRouters(routers)
+                .setDnsServers(dnsServers)
+                .setExcludedAddrs(excludedAddrs)
+                .build();
+
+        // Modifications to source objects should not affect builder or final parameters
+        final Inet4Address addedAddr = parseAddr("192.168.0.223");
+        routers.add(addedAddr);
+        dnsServers.add(addedAddr);
+        excludedAddrs.add(addedAddr);
+
+        assertEquals(TEST_DEFAULT_ROUTERS, params.defaultRouters);
+        assertEquals(TEST_LEASE_TIME_SECS, params.dhcpLeaseTimeSecs);
+        assertEquals(TEST_DNS_SERVERS, params.dnsServers);
+        assertEquals(TEST_LINKADDR, params.serverAddr);
+        assertEquals(TEST_MTU, params.linkMtu);
+
+        assertContains(params.excludedAddrs, TEST_EXCLUDED_ADDRS);
+        assertContains(params.excludedAddrs, TEST_DEFAULT_ROUTERS);
+        assertContains(params.excludedAddrs, TEST_DNS_SERVERS);
+        assertContains(params.excludedAddrs, TEST_SERVER_ADDR);
+
+        assertFalse("excludedAddrs should not contain " + addedAddr,
+                params.excludedAddrs.contains(addedAddr));
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_NegativeLeaseTime() throws InvalidParameterException {
+        mBuilder.setDhcpLeaseTimeSecs(-1).build();
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_LeaseTimeTooLarge() throws InvalidParameterException {
+        // Set lease time larger than max value for uint32
+        mBuilder.setDhcpLeaseTimeSecs(1L << 32).build();
+    }
+
+    @Test
+    public void testBuild_InfiniteLeaseTime() throws InvalidParameterException {
+        final long infiniteLeaseTime = 0xffffffffL;
+        final DhcpServingParams params = mBuilder
+                .setDhcpLeaseTimeSecs(infiniteLeaseTime).build();
+        assertEquals(infiniteLeaseTime, params.dhcpLeaseTimeSecs);
+        assertTrue(params.dhcpLeaseTimeSecs > 0L);
+    }
+
+    @Test
+    public void testBuild_UnsetMtu() throws InvalidParameterException {
+        final DhcpServingParams params = mBuilder.setLinkMtu(MTU_UNSET).build();
+        assertEquals(MTU_UNSET, params.linkMtu);
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_MtuTooSmall() throws InvalidParameterException {
+        mBuilder.setLinkMtu(20).build();
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_MtuTooLarge() throws InvalidParameterException {
+        mBuilder.setLinkMtu(65_536).build();
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_IPv6Addr() throws InvalidParameterException {
+        mBuilder.setServerAddr(new LinkAddress(parseNumericAddress("fe80::1111"), 120)).build();
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_PrefixTooLarge() throws InvalidParameterException {
+        mBuilder.setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 15)).build();
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_PrefixTooSmall() throws InvalidParameterException {
+        mBuilder.setDefaultRouters(Collections.singleton(parseAddr("192.168.0.254")))
+                .setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 31))
+                .build();
+    }
+
+    @Test(expected = InvalidParameterException.class)
+    public void testBuild_RouterNotInPrefix() throws InvalidParameterException {
+        mBuilder.setDefaultRouters(Collections.singleton(parseAddr("192.168.254.254"))).build();
+    }
+
+    private static <T> void assertContains(@NonNull Set<T> set, @NonNull Set<T> subset) {
+        for (final T elem : subset) {
+            assertContains(set, elem);
+        }
+    }
+
+    private static <T> void assertContains(@NonNull Set<T> set, @Nullable T elem) {
+        assertTrue("Set does not contain " + elem, set.contains(elem));
+    }
+
+    @NonNull
+    private static Inet4Address parseAddr(@NonNull String inet4Addr) {
+        return (Inet4Address) parseNumericAddress(inet4Addr);
+    }
+}
