diff --git a/Android.bp b/Android.bp
index 2f7d599..a2da0a0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -24,7 +24,7 @@
         ":services-networkstack-shared-srcs",
     ],
     static_libs: [
-        "dhcp-packet-lib",
+        "services-netlink-lib",
     ]
 }
 
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7f8bb93..5ab833b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -28,6 +28,7 @@
     <!-- Launch captive portal app as specific user -->
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
     <uses-permission android:name="android.permission.NETWORK_STACK" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
     <application
         android:label="NetworkStack"
         android:defaultToDeviceProtectedStorage="true"
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java
new file mode 100644
index 0000000..50c4dfc
--- /dev/null
+++ b/src/android/net/apf/ApfFilter.java
@@ -0,0 +1,1591 @@
+/*
+ * 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.apf;
+
+import static android.net.util.SocketUtils.makePacketSocketAddress;
+import static android.system.OsConstants.AF_PACKET;
+import static android.system.OsConstants.ARPHRD_ETHER;
+import static android.system.OsConstants.ETH_P_ARP;
+import static android.system.OsConstants.ETH_P_IP;
+import static android.system.OsConstants.ETH_P_IPV6;
+import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_RAW;
+
+import static com.android.internal.util.BitUtils.bytesToBEInt;
+import static com.android.internal.util.BitUtils.getUint16;
+import static com.android.internal.util.BitUtils.getUint32;
+import static com.android.internal.util.BitUtils.getUint8;
+import static com.android.internal.util.BitUtils.uint32;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
+
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.NetworkUtils;
+import android.net.apf.ApfGenerator.IllegalInstructionException;
+import android.net.apf.ApfGenerator.Register;
+import android.net.ip.IpClient.IpClientCallbacksWrapper;
+import android.net.metrics.ApfProgramEvent;
+import android.net.metrics.ApfStats;
+import android.net.metrics.IpConnectivityLog;
+import android.net.metrics.RaEvent;
+import android.net.util.InterfaceParams;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.HexDump;
+import com.android.internal.util.IndentingPrintWriter;
+
+import libcore.io.IoBridge;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * For networks that support packet filtering via APF programs, {@code ApfFilter}
+ * listens for IPv6 ICMPv6 router advertisements (RAs) and generates APF programs to
+ * filter out redundant duplicate ones.
+ *
+ * Threading model:
+ * A collection of RAs we've received is kept in mRas. Generating APF programs uses mRas to
+ * know what RAs to filter for, thus generating APF programs is dependent on mRas.
+ * mRas can be accessed by multiple threads:
+ * - ReceiveThread, which listens for RAs and adds them to mRas, and generates APF programs.
+ * - callers of:
+ *    - setMulticastFilter(), which can cause an APF program to be generated.
+ *    - dump(), which dumps mRas among other things.
+ *    - shutdown(), which clears mRas.
+ * So access to mRas is synchronized.
+ *
+ * @hide
+ */
+public class ApfFilter {
+
+    // Helper class for specifying functional filter parameters.
+    public static class ApfConfiguration {
+        public ApfCapabilities apfCapabilities;
+        public boolean multicastFilter;
+        public boolean ieee802_3Filter;
+        public int[] ethTypeBlackList;
+    }
+
+    // Enums describing the outcome of receiving an RA packet.
+    private static enum ProcessRaResult {
+        MATCH,          // Received RA matched a known RA
+        DROPPED,        // Received RA ignored due to MAX_RAS
+        PARSE_ERROR,    // Received RA could not be parsed
+        ZERO_LIFETIME,  // Received RA had 0 lifetime
+        UPDATE_NEW_RA,  // APF program updated for new RA
+        UPDATE_EXPIRY   // APF program updated for expiry
+    }
+
+    /**
+     * APF packet counters.
+     *
+     * Packet counters are 32bit big-endian values, and allocated near the end of the APF data
+     * buffer, using negative byte offsets, where -4 is equivalent to maximumApfProgramSize - 4,
+     * the last writable 32bit word.
+     */
+    @VisibleForTesting
+    public static enum Counter {
+        RESERVED_OOB,  // Points to offset 0 from the end of the buffer (out-of-bounds)
+        TOTAL_PACKETS,
+        PASSED_ARP,
+        PASSED_DHCP,
+        PASSED_IPV4,
+        PASSED_IPV6_NON_ICMP,
+        PASSED_IPV4_UNICAST,
+        PASSED_IPV6_ICMP,
+        PASSED_IPV6_UNICAST_NON_ICMP,
+        PASSED_ARP_NON_IPV4,
+        PASSED_ARP_UNKNOWN,
+        PASSED_ARP_UNICAST_REPLY,
+        PASSED_NON_IP_UNICAST,
+        DROPPED_ETH_BROADCAST,
+        DROPPED_RA,
+        DROPPED_GARP_REPLY,
+        DROPPED_ARP_OTHER_HOST,
+        DROPPED_IPV4_L2_BROADCAST,
+        DROPPED_IPV4_BROADCAST_ADDR,
+        DROPPED_IPV4_BROADCAST_NET,
+        DROPPED_IPV4_MULTICAST,
+        DROPPED_IPV6_ROUTER_SOLICITATION,
+        DROPPED_IPV6_MULTICAST_NA,
+        DROPPED_IPV6_MULTICAST,
+        DROPPED_IPV6_MULTICAST_PING,
+        DROPPED_IPV6_NON_ICMP_MULTICAST,
+        DROPPED_802_3_FRAME,
+        DROPPED_ETHERTYPE_BLACKLISTED,
+        DROPPED_ARP_REPLY_SPA_NO_HOST;
+
+        // Returns the negative byte offset from the end of the APF data segment for
+        // a given counter.
+        public int offset() {
+            return - this.ordinal() * 4;  // Currently, all counters are 32bit long.
+        }
+
+        // Returns the total size of the data segment in bytes.
+        public static int totalSize() {
+            return (Counter.class.getEnumConstants().length - 1) * 4;
+        }
+    }
+
+    /**
+     * When APFv4 is supported, loads R1 with the offset of the specified counter.
+     */
+    private void maybeSetupCounter(ApfGenerator gen, Counter c) {
+        if (mApfCapabilities.hasDataAccess()) {
+            gen.addLoadImmediate(Register.R1, c.offset());
+        }
+    }
+
+    // When APFv4 is supported, these point to the trampolines generated by emitEpilogue().
+    // Otherwise, they're just aliases for PASS_LABEL and DROP_LABEL.
+    private final String mCountAndPassLabel;
+    private final String mCountAndDropLabel;
+
+    // Thread to listen for RAs.
+    @VisibleForTesting
+    class ReceiveThread extends Thread {
+        private final byte[] mPacket = new byte[1514];
+        private final FileDescriptor mSocket;
+        private final long mStart = SystemClock.elapsedRealtime();
+
+        private int mReceivedRas = 0;
+        private int mMatchingRas = 0;
+        private int mDroppedRas = 0;
+        private int mParseErrors = 0;
+        private int mZeroLifetimeRas = 0;
+        private int mProgramUpdates = 0;
+
+        private volatile boolean mStopped;
+
+        public ReceiveThread(FileDescriptor socket) {
+            mSocket = socket;
+        }
+
+        public void halt() {
+            mStopped = true;
+            try {
+                // Interrupts the read() call the thread is blocked in.
+                IoBridge.closeAndSignalBlockedThreads(mSocket);
+            } catch (IOException ignored) {}
+        }
+
+        @Override
+        public void run() {
+            log("begin monitoring");
+            while (!mStopped) {
+                try {
+                    int length = Os.read(mSocket, mPacket, 0, mPacket.length);
+                    updateStats(processRa(mPacket, length));
+                } catch (IOException|ErrnoException e) {
+                    if (!mStopped) {
+                        Log.e(TAG, "Read error", e);
+                    }
+                }
+            }
+            logStats();
+        }
+
+        private void updateStats(ProcessRaResult result) {
+            mReceivedRas++;
+            switch(result) {
+                case MATCH:
+                    mMatchingRas++;
+                    return;
+                case DROPPED:
+                    mDroppedRas++;
+                    return;
+                case PARSE_ERROR:
+                    mParseErrors++;
+                    return;
+                case ZERO_LIFETIME:
+                    mZeroLifetimeRas++;
+                    return;
+                case UPDATE_EXPIRY:
+                    mMatchingRas++;
+                    mProgramUpdates++;
+                    return;
+                case UPDATE_NEW_RA:
+                    mProgramUpdates++;
+                    return;
+            }
+        }
+
+        private void logStats() {
+            final long nowMs = SystemClock.elapsedRealtime();
+            synchronized (this) {
+                final ApfStats stats = new ApfStats.Builder()
+                        .setReceivedRas(mReceivedRas)
+                        .setMatchingRas(mMatchingRas)
+                        .setDroppedRas(mDroppedRas)
+                        .setParseErrors(mParseErrors)
+                        .setZeroLifetimeRas(mZeroLifetimeRas)
+                        .setProgramUpdates(mProgramUpdates)
+                        .setDurationMs(nowMs - mStart)
+                        .setMaxProgramSize(mApfCapabilities.maximumApfProgramSize)
+                        .setProgramUpdatesAll(mNumProgramUpdates)
+                        .setProgramUpdatesAllowingMulticast(mNumProgramUpdatesAllowingMulticast)
+                        .build();
+                mMetricsLog.log(stats);
+                logApfProgramEventLocked(nowMs / DateUtils.SECOND_IN_MILLIS);
+            }
+        }
+    }
+
+    private static final String TAG = "ApfFilter";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false;
+
+    private static final int ETH_HEADER_LEN = 14;
+    private static final int ETH_DEST_ADDR_OFFSET = 0;
+    private static final int ETH_ETHERTYPE_OFFSET = 12;
+    private static final int ETH_TYPE_MIN = 0x0600;
+    private static final int ETH_TYPE_MAX = 0xFFFF;
+    private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
+            {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
+    // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN.
+    private static final int IPV4_FRAGMENT_OFFSET_OFFSET = ETH_HEADER_LEN + 6;
+    // Endianness is not an issue for this constant because the APF interpreter always operates in
+    // network byte order.
+    private static final int IPV4_FRAGMENT_OFFSET_MASK = 0x1fff;
+    private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
+    private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
+    private static final int IPV4_ANY_HOST_ADDRESS = 0;
+    private static final int IPV4_BROADCAST_ADDRESS = -1; // 255.255.255.255
+
+    // Traffic class and Flow label are not byte aligned. Luckily we
+    // don't care about either value so we'll consider bytes 1-3 of the
+    // IPv6 header as don't care.
+    private static final int IPV6_FLOW_LABEL_OFFSET = ETH_HEADER_LEN + 1;
+    private static final int IPV6_FLOW_LABEL_LEN = 3;
+    private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6;
+    private static final int IPV6_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 8;
+    private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24;
+    private static final int IPV6_HEADER_LEN = 40;
+    // The IPv6 all nodes address ff02::1
+    private static final byte[] IPV6_ALL_NODES_ADDRESS =
+            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+    private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
+
+    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
+    private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 2;
+    private static final int UDP_HEADER_LEN = 8;
+
+    private static final int DHCP_CLIENT_PORT = 68;
+    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
+    private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
+
+    private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN;
+    private static final byte[] ARP_IPV4_HEADER = {
+            0, 1, // Hardware type: Ethernet (1)
+            8, 0, // Protocol type: IP (0x0800)
+            6,    // Hardware size: 6
+            4,    // Protocol size: 4
+    };
+    private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
+    // Opcode: ARP request (0x0001), ARP reply (0x0002)
+    private static final short ARP_OPCODE_REQUEST = 1;
+    private static final short ARP_OPCODE_REPLY = 2;
+    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
+    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
+    // Do not log ApfProgramEvents whose actual lifetimes was less than this.
+    private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2;
+    // Limit on the Black List size to cap on program usage for this
+    // TODO: Select a proper max length
+    private static final int APF_MAX_ETH_TYPE_BLACK_LIST_LEN = 20;
+
+    private final ApfCapabilities mApfCapabilities;
+    private final IpClientCallbacksWrapper mIpClientCallback;
+    private final InterfaceParams mInterfaceParams;
+    private final IpConnectivityLog mMetricsLog;
+
+    @VisibleForTesting
+    byte[] mHardwareAddress;
+    @VisibleForTesting
+    ReceiveThread mReceiveThread;
+    @GuardedBy("this")
+    private long mUniqueCounter;
+    @GuardedBy("this")
+    private boolean mMulticastFilter;
+    @GuardedBy("this")
+    private boolean mInDozeMode;
+    private final boolean mDrop802_3Frames;
+    private final int[] mEthTypeBlackList;
+
+    // Detects doze mode state transitions.
+    private final BroadcastReceiver mDeviceIdleReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
+                PowerManager powerManager =
+                        (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+                final boolean deviceIdle = powerManager.isDeviceIdleMode();
+                setDozeMode(deviceIdle);
+            }
+        }
+    };
+    private final Context mContext;
+
+    // Our IPv4 address, if we have just one, otherwise null.
+    @GuardedBy("this")
+    private byte[] mIPv4Address;
+    // The subnet prefix length of our IPv4 network. Only valid if mIPv4Address is not null.
+    @GuardedBy("this")
+    private int mIPv4PrefixLength;
+
+    @VisibleForTesting
+    ApfFilter(Context context, ApfConfiguration config, InterfaceParams ifParams,
+            IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) {
+        mApfCapabilities = config.apfCapabilities;
+        mIpClientCallback = ipClientCallback;
+        mInterfaceParams = ifParams;
+        mMulticastFilter = config.multicastFilter;
+        mDrop802_3Frames = config.ieee802_3Filter;
+        mContext = context;
+
+        if (mApfCapabilities.hasDataAccess()) {
+            mCountAndPassLabel = "countAndPass";
+            mCountAndDropLabel = "countAndDrop";
+        } else {
+            // APFv4 unsupported: turn jumps to the counter trampolines to immediately PASS or DROP,
+            // preserving the original pre-APFv4 behavior.
+            mCountAndPassLabel = ApfGenerator.PASS_LABEL;
+            mCountAndDropLabel = ApfGenerator.DROP_LABEL;
+        }
+
+        // Now fill the black list from the passed array
+        mEthTypeBlackList = filterEthTypeBlackList(config.ethTypeBlackList);
+
+        mMetricsLog = log;
+
+        // TODO: ApfFilter should not generate programs until IpClient sends provisioning success.
+        maybeStartFilter();
+
+        // Listen for doze-mode transition changes to enable/disable the IPv6 multicast filter.
+        mContext.registerReceiver(mDeviceIdleReceiver,
+                new IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED));
+    }
+
+    public synchronized void setDataSnapshot(byte[] data) {
+        mDataSnapshot = data;
+    }
+
+    private void log(String s) {
+        Log.d(TAG, "(" + mInterfaceParams.name + "): " + s);
+    }
+
+    @GuardedBy("this")
+    private long getUniqueNumberLocked() {
+        return mUniqueCounter++;
+    }
+
+    @GuardedBy("this")
+    private static int[] filterEthTypeBlackList(int[] ethTypeBlackList) {
+        ArrayList<Integer> bl = new ArrayList<Integer>();
+
+        for (int p : ethTypeBlackList) {
+            // Check if the protocol is a valid ether type
+            if ((p < ETH_TYPE_MIN) || (p > ETH_TYPE_MAX)) {
+                continue;
+            }
+
+            // Check if the protocol is not repeated in the passed array
+            if (bl.contains(p)) {
+                continue;
+            }
+
+            // Check if list reach its max size
+            if (bl.size() == APF_MAX_ETH_TYPE_BLACK_LIST_LEN) {
+                Log.w(TAG, "Passed EthType Black List size too large (" + bl.size() +
+                        ") using top " + APF_MAX_ETH_TYPE_BLACK_LIST_LEN + " protocols");
+                break;
+            }
+
+            // Now add the protocol to the list
+            bl.add(p);
+        }
+
+        return bl.stream().mapToInt(Integer::intValue).toArray();
+    }
+
+    /**
+     * Attempt to start listening for RAs and, if RAs are received, generating and installing
+     * filters to ignore useless RAs.
+     */
+    @VisibleForTesting
+    void maybeStartFilter() {
+        FileDescriptor socket;
+        try {
+            mHardwareAddress = mInterfaceParams.macAddr.toByteArray();
+            synchronized(this) {
+                // Clear the APF memory to reset all counters upon connecting to the first AP
+                // in an SSID. This is limited to APFv4 devices because this large write triggers
+                // a crash on some older devices (b/78905546).
+                if (mApfCapabilities.hasDataAccess()) {
+                    byte[] zeroes = new byte[mApfCapabilities.maximumApfProgramSize];
+                    mIpClientCallback.installPacketFilter(zeroes);
+                }
+
+                // Install basic filters
+                installNewProgramLocked();
+            }
+            socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6);
+            SocketAddress addr = makePacketSocketAddress(
+                    (short) ETH_P_IPV6, mInterfaceParams.index);
+            Os.bind(socket, addr);
+            NetworkUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat);
+        } catch(SocketException|ErrnoException e) {
+            Log.e(TAG, "Error starting filter", e);
+            return;
+        }
+        mReceiveThread = new ReceiveThread(socket);
+        mReceiveThread.start();
+    }
+
+    // Returns seconds since device boot.
+    @VisibleForTesting
+    protected long currentTimeSeconds() {
+        return SystemClock.elapsedRealtime() / DateUtils.SECOND_IN_MILLIS;
+    }
+
+    public static class InvalidRaException extends Exception {
+        public InvalidRaException(String m) {
+            super(m);
+        }
+    }
+
+    // A class to hold information about an RA.
+    @VisibleForTesting
+    class Ra {
+        // From RFC4861:
+        private static final int ICMP6_RA_HEADER_LEN = 16;
+        private static final int ICMP6_RA_CHECKSUM_OFFSET =
+                ETH_HEADER_LEN + IPV6_HEADER_LEN + 2;
+        private static final int ICMP6_RA_CHECKSUM_LEN = 2;
+        private static final int ICMP6_RA_OPTION_OFFSET =
+                ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
+        private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
+                ETH_HEADER_LEN + IPV6_HEADER_LEN + 6;
+        private static final int ICMP6_RA_ROUTER_LIFETIME_LEN = 2;
+        // Prefix information option.
+        private static final int ICMP6_PREFIX_OPTION_TYPE = 3;
+        private static final int ICMP6_PREFIX_OPTION_LEN = 32;
+        private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET = 4;
+        private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN = 4;
+        private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8;
+        private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN = 4;
+
+        // From RFC6106: Recursive DNS Server option
+        private static final int ICMP6_RDNSS_OPTION_TYPE = 25;
+        // From RFC6106: DNS Search List option
+        private static final int ICMP6_DNSSL_OPTION_TYPE = 31;
+
+        // From RFC4191: Route Information option
+        private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24;
+        // Above three options all have the same format:
+        private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4;
+        private static final int ICMP6_4_BYTE_LIFETIME_LEN = 4;
+
+        // Note: mPacket's position() cannot be assumed to be reset.
+        private final ByteBuffer mPacket;
+        // List of binary ranges that include the whole packet except the lifetimes.
+        // Pairs consist of offset and length.
+        private final ArrayList<Pair<Integer, Integer>> mNonLifetimes =
+                new ArrayList<Pair<Integer, Integer>>();
+        // Minimum lifetime in packet
+        long mMinLifetime;
+        // When the packet was last captured, in seconds since Unix Epoch
+        long mLastSeen;
+
+        // For debugging only. Offsets into the packet where PIOs are.
+        private final ArrayList<Integer> mPrefixOptionOffsets = new ArrayList<>();
+
+        // For debugging only. Offsets into the packet where RDNSS options are.
+        private final ArrayList<Integer> mRdnssOptionOffsets = new ArrayList<>();
+
+        // For debugging only. How many times this RA was seen.
+        int seenCount = 0;
+
+        // For debugging only. Returns the hex representation of the last matching packet.
+        String getLastMatchingPacket() {
+            return HexDump.toHexString(mPacket.array(), 0, mPacket.capacity(),
+                    false /* lowercase */);
+        }
+
+        // For debugging only. Returns the string representation of the IPv6 address starting at
+        // position pos in the packet.
+        private String IPv6AddresstoString(int pos) {
+            try {
+                byte[] array = mPacket.array();
+                // Can't just call copyOfRange() and see if it throws, because if it reads past the
+                // end it pads with zeros instead of throwing.
+                if (pos < 0 || pos + 16 > array.length || pos + 16 < pos) {
+                    return "???";
+                }
+                byte[] addressBytes = Arrays.copyOfRange(array, pos, pos + 16);
+                InetAddress address = (Inet6Address) InetAddress.getByAddress(addressBytes);
+                return address.getHostAddress();
+            } catch (UnsupportedOperationException e) {
+                // array() failed. Cannot happen, mPacket is array-backed and read-write.
+                return "???";
+            } catch (ClassCastException|UnknownHostException e) {
+                // Cannot happen.
+                return "???";
+            }
+        }
+
+        // Can't be static because it's in a non-static inner class.
+        // TODO: Make this static once RA is its own class.
+        private void prefixOptionToString(StringBuffer sb, int offset) {
+            String prefix = IPv6AddresstoString(offset + 16);
+            int length = getUint8(mPacket, offset + 2);
+            long valid = getUint32(mPacket, offset + 4);
+            long preferred = getUint32(mPacket, offset + 8);
+            sb.append(String.format("%s/%d %ds/%ds ", prefix, length, valid, preferred));
+        }
+
+        private void rdnssOptionToString(StringBuffer sb, int offset) {
+            int optLen = getUint8(mPacket, offset + 1) * 8;
+            if (optLen < 24) return;  // Malformed or empty.
+            long lifetime = getUint32(mPacket, offset + 4);
+            int numServers = (optLen - 8) / 16;
+            sb.append("DNS ").append(lifetime).append("s");
+            for (int server = 0; server < numServers; server++) {
+                sb.append(" ").append(IPv6AddresstoString(offset + 8 + 16 * server));
+            }
+        }
+
+        public String toString() {
+            try {
+                StringBuffer sb = new StringBuffer();
+                sb.append(String.format("RA %s -> %s %ds ",
+                        IPv6AddresstoString(IPV6_SRC_ADDR_OFFSET),
+                        IPv6AddresstoString(IPV6_DEST_ADDR_OFFSET),
+                        getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET)));
+                for (int i: mPrefixOptionOffsets) {
+                    prefixOptionToString(sb, i);
+                }
+                for (int i: mRdnssOptionOffsets) {
+                    rdnssOptionToString(sb, i);
+                }
+                return sb.toString();
+            } catch (BufferUnderflowException|IndexOutOfBoundsException e) {
+                return "<Malformed RA>";
+            }
+        }
+
+        /**
+         * Add a binary range of the packet that does not include a lifetime to mNonLifetimes.
+         * Assumes mPacket.position() is as far as we've parsed the packet.
+         * @param lastNonLifetimeStart offset within packet of where the last binary range of
+         *                             data not including a lifetime.
+         * @param lifetimeOffset offset from mPacket.position() to the next lifetime data.
+         * @param lifetimeLength length of the next lifetime data.
+         * @return offset within packet of where the next binary range of data not including
+         *         a lifetime. This can be passed into the next invocation of this function
+         *         via {@code lastNonLifetimeStart}.
+         */
+        private int addNonLifetime(int lastNonLifetimeStart, int lifetimeOffset,
+                int lifetimeLength) {
+            lifetimeOffset += mPacket.position();
+            mNonLifetimes.add(new Pair<Integer, Integer>(lastNonLifetimeStart,
+                    lifetimeOffset - lastNonLifetimeStart));
+            return lifetimeOffset + lifetimeLength;
+        }
+
+        private int addNonLifetimeU32(int lastNonLifetimeStart) {
+            return addNonLifetime(lastNonLifetimeStart,
+                    ICMP6_4_BYTE_LIFETIME_OFFSET, ICMP6_4_BYTE_LIFETIME_LEN);
+        }
+
+        // Note that this parses RA and may throw InvalidRaException (from
+        // Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException
+        // (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with
+        // specifications.
+        Ra(byte[] packet, int length) throws InvalidRaException {
+            if (length < ICMP6_RA_OPTION_OFFSET) {
+                throw new InvalidRaException("Not an ICMP6 router advertisement");
+            }
+
+            mPacket = ByteBuffer.wrap(Arrays.copyOf(packet, length));
+            mLastSeen = currentTimeSeconds();
+
+            // Sanity check packet in case a packet arrives before we attach RA filter
+            // to our packet socket. b/29586253
+            if (getUint16(mPacket, ETH_ETHERTYPE_OFFSET) != ETH_P_IPV6 ||
+                    getUint8(mPacket, IPV6_NEXT_HEADER_OFFSET) != IPPROTO_ICMPV6 ||
+                    getUint8(mPacket, ICMP6_TYPE_OFFSET) != ICMPV6_ROUTER_ADVERTISEMENT) {
+                throw new InvalidRaException("Not an ICMP6 router advertisement");
+            }
+
+
+            RaEvent.Builder builder = new RaEvent.Builder();
+
+            // Ignore the flow label and low 4 bits of traffic class.
+            int lastNonLifetimeStart = addNonLifetime(0,
+                    IPV6_FLOW_LABEL_OFFSET,
+                    IPV6_FLOW_LABEL_LEN);
+
+            // Ignore the checksum.
+            lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
+                    ICMP6_RA_CHECKSUM_OFFSET,
+                    ICMP6_RA_CHECKSUM_LEN);
+
+            // Parse router lifetime
+            lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
+                    ICMP6_RA_ROUTER_LIFETIME_OFFSET,
+                    ICMP6_RA_ROUTER_LIFETIME_LEN);
+            builder.updateRouterLifetime(getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET));
+
+            // Ensures that the RA is not truncated.
+            mPacket.position(ICMP6_RA_OPTION_OFFSET);
+            while (mPacket.hasRemaining()) {
+                final int position = mPacket.position();
+                final int optionType = getUint8(mPacket, position);
+                final int optionLength = getUint8(mPacket, position + 1) * 8;
+                long lifetime;
+                switch (optionType) {
+                    case ICMP6_PREFIX_OPTION_TYPE:
+                        // Parse valid lifetime
+                        lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
+                                ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
+                                ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN);
+                        lifetime = getUint32(mPacket,
+                                position + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET);
+                        builder.updatePrefixValidLifetime(lifetime);
+                        // Parse preferred lifetime
+                        lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
+                                ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
+                                ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN);
+                        lifetime = getUint32(mPacket,
+                                position + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET);
+                        builder.updatePrefixPreferredLifetime(lifetime);
+                        mPrefixOptionOffsets.add(position);
+                        break;
+                    // These three options have the same lifetime offset and size, and
+                    // are processed with the same specialized addNonLifetimeU32:
+                    case ICMP6_RDNSS_OPTION_TYPE:
+                        mRdnssOptionOffsets.add(position);
+                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
+                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
+                        builder.updateRdnssLifetime(lifetime);
+                        break;
+                    case ICMP6_ROUTE_INFO_OPTION_TYPE:
+                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
+                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
+                        builder.updateRouteInfoLifetime(lifetime);
+                        break;
+                    case ICMP6_DNSSL_OPTION_TYPE:
+                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
+                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
+                        builder.updateDnsslLifetime(lifetime);
+                        break;
+                    default:
+                        // RFC4861 section 4.2 dictates we ignore unknown options for fowards
+                        // compatibility.
+                        break;
+                }
+                if (optionLength <= 0) {
+                    throw new InvalidRaException(String.format(
+                        "Invalid option length opt=%d len=%d", optionType, optionLength));
+                }
+                mPacket.position(position + optionLength);
+            }
+            // Mark non-lifetime bytes since last lifetime.
+            addNonLifetime(lastNonLifetimeStart, 0, 0);
+            mMinLifetime = minLifetime(packet, length);
+            mMetricsLog.log(builder.build());
+        }
+
+        // Ignoring lifetimes (which may change) does {@code packet} match this RA?
+        boolean matches(byte[] packet, int length) {
+            if (length != mPacket.capacity()) return false;
+            byte[] referencePacket = mPacket.array();
+            for (Pair<Integer, Integer> nonLifetime : mNonLifetimes) {
+                for (int i = nonLifetime.first; i < (nonLifetime.first + nonLifetime.second); i++) {
+                    if (packet[i] != referencePacket[i]) return false;
+                }
+            }
+            return true;
+        }
+
+        // What is the minimum of all lifetimes within {@code packet} in seconds?
+        // Precondition: matches(packet, length) already returned true.
+        long minLifetime(byte[] packet, int length) {
+            long minLifetime = Long.MAX_VALUE;
+            // Wrap packet in ByteBuffer so we can read big-endian values easily
+            ByteBuffer byteBuffer = ByteBuffer.wrap(packet);
+            for (int i = 0; (i + 1) < mNonLifetimes.size(); i++) {
+                int offset = mNonLifetimes.get(i).first + mNonLifetimes.get(i).second;
+
+                // The flow label is in mNonLifetimes, but it's not a lifetime.
+                if (offset == IPV6_FLOW_LABEL_OFFSET) {
+                    continue;
+                }
+
+                // The checksum is in mNonLifetimes, but it's not a lifetime.
+                if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
+                    continue;
+                }
+
+                final int lifetimeLength = mNonLifetimes.get(i+1).first - offset;
+                final long optionLifetime;
+                switch (lifetimeLength) {
+                    case 2:
+                        optionLifetime = getUint16(byteBuffer, offset);
+                        break;
+                    case 4:
+                        optionLifetime = getUint32(byteBuffer, offset);
+                        break;
+                    default:
+                        throw new IllegalStateException("bogus lifetime size " + lifetimeLength);
+                }
+                minLifetime = Math.min(minLifetime, optionLifetime);
+            }
+            return minLifetime;
+        }
+
+        // How many seconds does this RA's have to live, taking into account the fact
+        // that we might have seen it a while ago.
+        long currentLifetime() {
+            return mMinLifetime - (currentTimeSeconds() - mLastSeen);
+        }
+
+        boolean isExpired() {
+            // TODO: We may want to handle 0 lifetime RAs differently, if they are common. We'll
+            // have to calculte the filter lifetime specially as a fraction of 0 is still 0.
+            return currentLifetime() <= 0;
+        }
+
+        // Append a filter for this RA to {@code gen}. Jump to DROP_LABEL if it should be dropped.
+        // Jump to the next filter if packet doesn't match this RA.
+        @GuardedBy("ApfFilter.this")
+        long generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
+            String nextFilterLabel = "Ra" + getUniqueNumberLocked();
+            // Skip if packet is not the right size
+            gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
+            gen.addJumpIfR0NotEquals(mPacket.capacity(), nextFilterLabel);
+            int filterLifetime = (int)(currentLifetime() / FRACTION_OF_LIFETIME_TO_FILTER);
+            // Skip filter if expired
+            gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT);
+            gen.addJumpIfR0GreaterThan(filterLifetime, nextFilterLabel);
+            for (int i = 0; i < mNonLifetimes.size(); i++) {
+                // Generate code to match the packet bytes
+                Pair<Integer, Integer> nonLifetime = mNonLifetimes.get(i);
+                // Don't generate JNEBS instruction for 0 bytes as it always fails the
+                // ASSERT_FORWARD_IN_PROGRAM(pc + cmp_imm - 1) check where cmp_imm is
+                // the number of bytes to compare. nonLifetime is zero between the
+                // valid and preferred lifetimes in the prefix option.
+                if (nonLifetime.second != 0) {
+                    gen.addLoadImmediate(Register.R0, nonLifetime.first);
+                    gen.addJumpIfBytesNotEqual(Register.R0,
+                            Arrays.copyOfRange(mPacket.array(), nonLifetime.first,
+                                               nonLifetime.first + nonLifetime.second),
+                            nextFilterLabel);
+                }
+                // Generate code to test the lifetimes haven't gone down too far
+                if ((i + 1) < mNonLifetimes.size()) {
+                    Pair<Integer, Integer> nextNonLifetime = mNonLifetimes.get(i + 1);
+                    int offset = nonLifetime.first + nonLifetime.second;
+
+                    // Skip the Flow label.
+                    if (offset == IPV6_FLOW_LABEL_OFFSET) {
+                        continue;
+                    }
+                    // Skip the checksum.
+                    if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
+                        continue;
+                    }
+                    int length = nextNonLifetime.first - offset;
+                    switch (length) {
+                        case 4: gen.addLoad32(Register.R0, offset); break;
+                        case 2: gen.addLoad16(Register.R0, offset); break;
+                        default: throw new IllegalStateException("bogus lifetime size " + length);
+                    }
+                    gen.addJumpIfR0LessThan(filterLifetime, nextFilterLabel);
+                }
+            }
+            maybeSetupCounter(gen, Counter.DROPPED_RA);
+            gen.addJump(mCountAndDropLabel);
+            gen.defineLabel(nextFilterLabel);
+            return filterLifetime;
+        }
+    }
+
+    // Maximum number of RAs to filter for.
+    private static final int MAX_RAS = 10;
+
+    @GuardedBy("this")
+    private ArrayList<Ra> mRas = new ArrayList<Ra>();
+
+    // There is always some marginal benefit to updating the installed APF program when an RA is
+    // seen because we can extend the program's lifetime slightly, but there is some cost to
+    // updating the program, so don't bother unless the program is going to expire soon. This
+    // constant defines "soon" in seconds.
+    private static final long MAX_PROGRAM_LIFETIME_WORTH_REFRESHING = 30;
+    // We don't want to filter an RA for it's whole lifetime as it'll be expired by the time we ever
+    // see a refresh.  Using half the lifetime might be a good idea except for the fact that
+    // packets may be dropped, so let's use 6.
+    private static final int FRACTION_OF_LIFETIME_TO_FILTER = 6;
+
+    // When did we last install a filter program? In seconds since Unix Epoch.
+    @GuardedBy("this")
+    private long mLastTimeInstalledProgram;
+    // How long should the last installed filter program live for? In seconds.
+    @GuardedBy("this")
+    private long mLastInstalledProgramMinLifetime;
+    @GuardedBy("this")
+    private ApfProgramEvent.Builder mLastInstallEvent;
+
+    // For debugging only. The last program installed.
+    @GuardedBy("this")
+    private byte[] mLastInstalledProgram;
+
+    /**
+     * For debugging only. Contains the latest APF buffer snapshot captured from the firmware.
+     *
+     * A typical size for this buffer is 4KB. It is present only if the WiFi HAL supports
+     * IWifiStaIface#readApfPacketFilterData(), and the APF interpreter advertised support for
+     * the opcodes to access the data buffer (LDDW and STDW).
+     */
+    @GuardedBy("this") @Nullable
+    private byte[] mDataSnapshot;
+
+    // How many times the program was updated since we started.
+    @GuardedBy("this")
+    private int mNumProgramUpdates = 0;
+    // How many times the program was updated since we started for allowing multicast traffic.
+    @GuardedBy("this")
+    private int mNumProgramUpdatesAllowingMulticast = 0;
+
+    /**
+     * Generate filter code to process ARP packets. Execution of this code ends in either the
+     * DROP_LABEL or PASS_LABEL and does not fall off the end.
+     * Preconditions:
+     *  - Packet being filtered is ARP
+     */
+    @GuardedBy("this")
+    private void generateArpFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
+        // Here's a basic summary of what the ARP filter program does:
+        //
+        // if not ARP IPv4
+        //   pass
+        // if not ARP IPv4 reply or request
+        //   pass
+        // if ARP reply source ip is 0.0.0.0
+        //   drop
+        // if unicast ARP reply
+        //   pass
+        // if interface has no IPv4 address
+        //   if target ip is 0.0.0.0
+        //      drop
+        // else
+        //   if target ip is not the interface ip
+        //      drop
+        // pass
+
+        final String checkTargetIPv4 = "checkTargetIPv4";
+
+        // Pass if not ARP IPv4.
+        gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
+        maybeSetupCounter(gen, Counter.PASSED_ARP_NON_IPV4);
+        gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, mCountAndPassLabel);
+
+        // Pass if unknown ARP opcode.
+        gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET);
+        gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check
+        maybeSetupCounter(gen, Counter.PASSED_ARP_UNKNOWN);
+        gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndPassLabel);
+
+        // Drop if ARP reply source IP is 0.0.0.0
+        gen.addLoad32(Register.R0, ARP_SOURCE_IP_ADDRESS_OFFSET);
+        maybeSetupCounter(gen, Counter.DROPPED_ARP_REPLY_SPA_NO_HOST);
+        gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
+
+        // Pass if unicast reply.
+        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
+        maybeSetupCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
+        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
+
+        // Either a unicast request, a unicast reply, or a broadcast reply.
+        gen.defineLabel(checkTargetIPv4);
+        if (mIPv4Address == null) {
+            // When there is no IPv4 address, drop GARP replies (b/29404209).
+            gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
+            maybeSetupCounter(gen, Counter.DROPPED_GARP_REPLY);
+            gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
+        } else {
+            // When there is an IPv4 address, drop unicast/broadcast requests
+            // and broadcast replies with a different target IPv4 address.
+            gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
+            maybeSetupCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
+            gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, mCountAndDropLabel);
+        }
+
+        maybeSetupCounter(gen, Counter.PASSED_ARP);
+        gen.addJump(mCountAndPassLabel);
+    }
+
+    /**
+     * Generate filter code to process IPv4 packets. Execution of this code ends in either the
+     * DROP_LABEL or PASS_LABEL and does not fall off the end.
+     * Preconditions:
+     *  - Packet being filtered is IPv4
+     */
+    @GuardedBy("this")
+    private void generateIPv4FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
+        // Here's a basic summary of what the IPv4 filter program does:
+        //
+        // if filtering multicast (i.e. multicast lock not held):
+        //   if it's DHCP destined to our MAC:
+        //     pass
+        //   if it's L2 broadcast:
+        //     drop
+        //   if it's IPv4 multicast:
+        //     drop
+        //   if it's IPv4 broadcast:
+        //     drop
+        // pass
+
+        if (mMulticastFilter) {
+            final String skipDhcpv4Filter = "skip_dhcp_v4_filter";
+
+            // Pass DHCP addressed to us.
+            // Check it's UDP.
+            gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
+            gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipDhcpv4Filter);
+            // Check it's not a fragment. This matches the BPF filter installed by the DHCP client.
+            gen.addLoad16(Register.R0, IPV4_FRAGMENT_OFFSET_OFFSET);
+            gen.addJumpIfR0AnyBitsSet(IPV4_FRAGMENT_OFFSET_MASK, skipDhcpv4Filter);
+            // Check it's addressed to DHCP client port.
+            gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
+            gen.addLoad16Indexed(Register.R0, UDP_DESTINATION_PORT_OFFSET);
+            gen.addJumpIfR0NotEquals(DHCP_CLIENT_PORT, skipDhcpv4Filter);
+            // Check it's DHCP to our MAC address.
+            gen.addLoadImmediate(Register.R0, DHCP_CLIENT_MAC_OFFSET);
+            // NOTE: Relies on R1 containing IPv4 header offset.
+            gen.addAddR1();
+            gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, skipDhcpv4Filter);
+            maybeSetupCounter(gen, Counter.PASSED_DHCP);
+            gen.addJump(mCountAndPassLabel);
+
+            // Drop all multicasts/broadcasts.
+            gen.defineLabel(skipDhcpv4Filter);
+
+            // If IPv4 destination address is in multicast range, drop.
+            gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
+            gen.addAnd(0xf0);
+            maybeSetupCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
+            gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel);
+
+            // If IPv4 broadcast packet, drop regardless of L2 (b/30231088).
+            maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
+            gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET);
+            gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel);
+            if (mIPv4Address != null && mIPv4PrefixLength < 31) {
+                maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
+                int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength);
+                gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
+            }
+
+            // If L2 broadcast packet, drop.
+            // TODO: can we invert this condition to fall through to the common pass case below?
+            maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST);
+            gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
+            gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
+            maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
+            gen.addJump(mCountAndDropLabel);
+        }
+
+        // Otherwise, pass
+        maybeSetupCounter(gen, Counter.PASSED_IPV4);
+        gen.addJump(mCountAndPassLabel);
+    }
+
+
+    /**
+     * Generate filter code to process IPv6 packets. Execution of this code ends in either the
+     * DROP_LABEL or PASS_LABEL, or falls off the end for ICMPv6 packets.
+     * Preconditions:
+     *  - Packet being filtered is IPv6
+     */
+    @GuardedBy("this")
+    private void generateIPv6FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
+        // Here's a basic summary of what the IPv6 filter program does:
+        //
+        // if we're dropping multicast
+        //   if it's not IPCMv6 or it's ICMPv6 but we're in doze mode:
+        //     if it's multicast:
+        //       drop
+        //     pass
+        // if it's ICMPv6 RS to any:
+        //   drop
+        // if it's ICMPv6 NA to ff02::1:
+        //   drop
+
+        gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET);
+
+        // Drop multicast if the multicast filter is enabled.
+        if (mMulticastFilter) {
+            final String skipIPv6MulticastFilterLabel = "skipIPv6MulticastFilter";
+            final String dropAllIPv6MulticastsLabel = "dropAllIPv6Multicast";
+
+            // While in doze mode, drop ICMPv6 multicast pings, let the others pass.
+            // While awake, let all ICMPv6 multicasts through.
+            if (mInDozeMode) {
+                // Not ICMPv6? -> Proceed to multicast filtering
+                gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, dropAllIPv6MulticastsLabel);
+
+                // ICMPv6 but not ECHO? -> Skip the multicast filter.
+                // (ICMPv6 ECHO requests will go through the multicast filter below).
+                gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
+                gen.addJumpIfR0NotEquals(ICMPV6_ECHO_REQUEST_TYPE, skipIPv6MulticastFilterLabel);
+            } else {
+                gen.addJumpIfR0Equals(IPPROTO_ICMPV6, skipIPv6MulticastFilterLabel);
+            }
+
+            // Drop all other packets sent to ff00::/8 (multicast prefix).
+            gen.defineLabel(dropAllIPv6MulticastsLabel);
+            maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
+            gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET);
+            gen.addJumpIfR0Equals(0xff, mCountAndDropLabel);
+            // Not multicast. Pass.
+            maybeSetupCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
+            gen.addJump(mCountAndPassLabel);
+            gen.defineLabel(skipIPv6MulticastFilterLabel);
+        } else {
+            // If not ICMPv6, pass.
+            maybeSetupCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
+            gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel);
+        }
+
+        // If we got this far, the packet is ICMPv6.  Drop some specific types.
+
+        // Add unsolicited multicast neighbor announcements filter
+        String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
+        gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
+        // Drop all router solicitations (b/32833400)
+        maybeSetupCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
+        gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel);
+        // If not neighbor announcements, skip filter.
+        gen.addJumpIfR0NotEquals(ICMPV6_NEIGHBOR_ADVERTISEMENT, skipUnsolicitedMulticastNALabel);
+        // If to ff02::1, drop.
+        // TODO: Drop only if they don't contain the address of on-link neighbours.
+        gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
+        gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
+                skipUnsolicitedMulticastNALabel);
+        maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
+        gen.addJump(mCountAndDropLabel);
+        gen.defineLabel(skipUnsolicitedMulticastNALabel);
+    }
+
+    /**
+     * Begin generating an APF program to:
+     * <ul>
+     * <li>Drop/Pass 802.3 frames (based on policy)
+     * <li>Drop packets with EtherType within the Black List
+     * <li>Drop ARP requests not for us, if mIPv4Address is set,
+     * <li>Drop IPv4 broadcast packets, except DHCP destined to our MAC,
+     * <li>Drop IPv4 multicast packets, if mMulticastFilter,
+     * <li>Pass all other IPv4 packets,
+     * <li>Drop all broadcast non-IP non-ARP packets.
+     * <li>Pass all non-ICMPv6 IPv6 packets,
+     * <li>Pass all non-IPv4 and non-IPv6 packets,
+     * <li>Drop IPv6 ICMPv6 NAs to ff02::1.
+     * <li>Drop IPv6 ICMPv6 RSs.
+     * <li>Let execution continue off the end of the program for IPv6 ICMPv6 packets. This allows
+     *     insertion of RA filters here, or if there aren't any, just passes the packets.
+     * </ul>
+     */
+    @GuardedBy("this")
+    private ApfGenerator emitPrologueLocked() throws IllegalInstructionException {
+        // This is guaranteed to succeed because of the check in maybeCreate.
+        ApfGenerator gen = new ApfGenerator(mApfCapabilities.apfVersionSupported);
+
+        if (mApfCapabilities.hasDataAccess()) {
+            // Increment TOTAL_PACKETS
+            maybeSetupCounter(gen, Counter.TOTAL_PACKETS);
+            gen.addLoadData(Register.R0, 0);  // load counter
+            gen.addAdd(1);
+            gen.addStoreData(Register.R0, 0);  // write-back counter
+        }
+
+        // Here's a basic summary of what the initial program does:
+        //
+        // if it's a 802.3 Frame (ethtype < 0x0600):
+        //    drop or pass based on configurations
+        // if it has a ether-type that belongs to the black list
+        //    drop
+        // if it's ARP:
+        //   insert ARP filter to drop or pass these appropriately
+        // if it's IPv4:
+        //   insert IPv4 filter to drop or pass these appropriately
+        // if it's not IPv6:
+        //   if it's broadcast:
+        //     drop
+        //   pass
+        // insert IPv6 filter to drop, pass, or fall off the end for ICMPv6 packets
+
+        gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET);
+
+        if (mDrop802_3Frames) {
+            // drop 802.3 frames (ethtype < 0x0600)
+            maybeSetupCounter(gen, Counter.DROPPED_802_3_FRAME);
+            gen.addJumpIfR0LessThan(ETH_TYPE_MIN, mCountAndDropLabel);
+        }
+
+        // Handle ether-type black list
+        maybeSetupCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
+        for (int p : mEthTypeBlackList) {
+            gen.addJumpIfR0Equals(p, mCountAndDropLabel);
+        }
+
+        // Add ARP filters:
+        String skipArpFiltersLabel = "skipArpFilters";
+        gen.addJumpIfR0NotEquals(ETH_P_ARP, skipArpFiltersLabel);
+        generateArpFilterLocked(gen);
+        gen.defineLabel(skipArpFiltersLabel);
+
+        // Add IPv4 filters:
+        String skipIPv4FiltersLabel = "skipIPv4Filters";
+        // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not
+        // execute the ARP filter, since that filter does not fall through, but either drops or
+        // passes.
+        gen.addJumpIfR0NotEquals(ETH_P_IP, skipIPv4FiltersLabel);
+        generateIPv4FilterLocked(gen);
+        gen.defineLabel(skipIPv4FiltersLabel);
+
+        // Check for IPv6:
+        // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not
+        // execute the ARP or IPv4 filters, since those filters do not fall through, but either
+        // drop or pass.
+        String ipv6FilterLabel = "IPv6Filters";
+        gen.addJumpIfR0Equals(ETH_P_IPV6, ipv6FilterLabel);
+
+        // Drop non-IP non-ARP broadcasts, pass the rest
+        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
+        maybeSetupCounter(gen, Counter.PASSED_NON_IP_UNICAST);
+        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
+        maybeSetupCounter(gen, Counter.DROPPED_ETH_BROADCAST);
+        gen.addJump(mCountAndDropLabel);
+
+        // Add IPv6 filters:
+        gen.defineLabel(ipv6FilterLabel);
+        generateIPv6FilterLocked(gen);
+        return gen;
+    }
+
+    /**
+     * Append packet counting epilogue to the APF program.
+     *
+     * Currently, the epilogue consists of two trampolines which count passed and dropped packets
+     * before jumping to the actual PASS and DROP labels.
+     */
+    @GuardedBy("this")
+    private void emitEpilogue(ApfGenerator gen) throws IllegalInstructionException {
+        // If APFv4 is unsupported, no epilogue is necessary: if execution reached this far, it
+        // will just fall-through to the PASS label.
+        if (!mApfCapabilities.hasDataAccess()) return;
+
+        // Execution will reach the bottom of the program if none of the filters match,
+        // which will pass the packet to the application processor.
+        maybeSetupCounter(gen, Counter.PASSED_IPV6_ICMP);
+
+        // Append the count & pass trampoline, which increments the counter at the data address
+        // pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting
+        // the entire sequence inline for every counter.
+        gen.defineLabel(mCountAndPassLabel);
+        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
+        gen.addAdd(1);                     // R0++
+        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
+        gen.addJump(gen.PASS_LABEL);
+
+        // Same as above for the count & drop trampoline.
+        gen.defineLabel(mCountAndDropLabel);
+        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
+        gen.addAdd(1);                     // R0++
+        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
+        gen.addJump(gen.DROP_LABEL);
+    }
+
+    /**
+     * Generate and install a new filter program.
+     */
+    @GuardedBy("this")
+    @VisibleForTesting
+    void installNewProgramLocked() {
+        purgeExpiredRasLocked();
+        ArrayList<Ra> rasToFilter = new ArrayList<>();
+        final byte[] program;
+        long programMinLifetime = Long.MAX_VALUE;
+        long maximumApfProgramSize = mApfCapabilities.maximumApfProgramSize;
+        if (mApfCapabilities.hasDataAccess()) {
+            // Reserve space for the counters.
+            maximumApfProgramSize -= Counter.totalSize();
+        }
+
+        try {
+            // Step 1: Determine how many RA filters we can fit in the program.
+            ApfGenerator gen = emitPrologueLocked();
+
+            // The epilogue normally goes after the RA filters, but add it early to include its
+            // length when estimating the total.
+            emitEpilogue(gen);
+
+            // Can't fit the program even without any RA filters?
+            if (gen.programLengthOverEstimate() > maximumApfProgramSize) {
+                Log.e(TAG, "Program exceeds maximum size " + maximumApfProgramSize);
+                return;
+            }
+
+            for (Ra ra : mRas) {
+                ra.generateFilterLocked(gen);
+                // Stop if we get too big.
+                if (gen.programLengthOverEstimate() > maximumApfProgramSize) break;
+                rasToFilter.add(ra);
+            }
+
+            // Step 2: Actually generate the program
+            gen = emitPrologueLocked();
+            for (Ra ra : rasToFilter) {
+                programMinLifetime = Math.min(programMinLifetime, ra.generateFilterLocked(gen));
+            }
+            emitEpilogue(gen);
+            program = gen.generate();
+        } catch (IllegalInstructionException|IllegalStateException e) {
+            Log.e(TAG, "Failed to generate APF program.", e);
+            return;
+        }
+        final long now = currentTimeSeconds();
+        mLastTimeInstalledProgram = now;
+        mLastInstalledProgramMinLifetime = programMinLifetime;
+        mLastInstalledProgram = program;
+        mNumProgramUpdates++;
+
+        if (VDBG) {
+            hexDump("Installing filter: ", program, program.length);
+        }
+        mIpClientCallback.installPacketFilter(program);
+        logApfProgramEventLocked(now);
+        mLastInstallEvent = new ApfProgramEvent.Builder()
+                .setLifetime(programMinLifetime)
+                .setFilteredRas(rasToFilter.size())
+                .setCurrentRas(mRas.size())
+                .setProgramLength(program.length)
+                .setFlags(mIPv4Address != null, mMulticastFilter);
+    }
+
+    @GuardedBy("this")
+    private void logApfProgramEventLocked(long now) {
+        if (mLastInstallEvent == null) {
+            return;
+        }
+        ApfProgramEvent.Builder ev = mLastInstallEvent;
+        mLastInstallEvent = null;
+        final long actualLifetime = now - mLastTimeInstalledProgram;
+        ev.setActualLifetime(actualLifetime);
+        if (actualLifetime < APF_PROGRAM_EVENT_LIFETIME_THRESHOLD) {
+            return;
+        }
+        mMetricsLog.log(ev.build());
+    }
+
+    /**
+     * Returns {@code true} if a new program should be installed because the current one dies soon.
+     */
+    private boolean shouldInstallnewProgram() {
+        long expiry = mLastTimeInstalledProgram + mLastInstalledProgramMinLifetime;
+        return expiry < currentTimeSeconds() + MAX_PROGRAM_LIFETIME_WORTH_REFRESHING;
+    }
+
+    private void hexDump(String msg, byte[] packet, int length) {
+        log(msg + HexDump.toHexString(packet, 0, length, false /* lowercase */));
+    }
+
+    @GuardedBy("this")
+    private void purgeExpiredRasLocked() {
+        for (int i = 0; i < mRas.size();) {
+            if (mRas.get(i).isExpired()) {
+                log("Expiring " + mRas.get(i));
+                mRas.remove(i);
+            } else {
+                i++;
+            }
+        }
+    }
+
+    /**
+     * Process an RA packet, updating the list of known RAs and installing a new APF program
+     * if the current APF program should be updated.
+     * @return a ProcessRaResult enum describing what action was performed.
+     */
+    @VisibleForTesting
+    synchronized ProcessRaResult processRa(byte[] packet, int length) {
+        if (VDBG) hexDump("Read packet = ", packet, length);
+
+        // Have we seen this RA before?
+        for (int i = 0; i < mRas.size(); i++) {
+            Ra ra = mRas.get(i);
+            if (ra.matches(packet, length)) {
+                if (VDBG) log("matched RA " + ra);
+                // Update lifetimes.
+                ra.mLastSeen = currentTimeSeconds();
+                ra.mMinLifetime = ra.minLifetime(packet, length);
+                ra.seenCount++;
+
+                // Keep mRas in LRU order so as to prioritize generating filters for recently seen
+                // RAs. LRU prioritizes this because RA filters are generated in order from mRas
+                // until the filter program exceeds the maximum filter program size allowed by the
+                // chipset, so RAs appearing earlier in mRas are more likely to make it into the
+                // filter program.
+                // TODO: consider sorting the RAs in order of increasing expiry time as well.
+                // Swap to front of array.
+                mRas.add(0, mRas.remove(i));
+
+                // If the current program doesn't expire for a while, don't update.
+                if (shouldInstallnewProgram()) {
+                    installNewProgramLocked();
+                    return ProcessRaResult.UPDATE_EXPIRY;
+                }
+                return ProcessRaResult.MATCH;
+            }
+        }
+        purgeExpiredRasLocked();
+        // TODO: figure out how to proceed when we've received more then MAX_RAS RAs.
+        if (mRas.size() >= MAX_RAS) {
+            return ProcessRaResult.DROPPED;
+        }
+        final Ra ra;
+        try {
+            ra = new Ra(packet, length);
+        } catch (Exception e) {
+            Log.e(TAG, "Error parsing RA", e);
+            return ProcessRaResult.PARSE_ERROR;
+        }
+        // Ignore 0 lifetime RAs.
+        if (ra.isExpired()) {
+            return ProcessRaResult.ZERO_LIFETIME;
+        }
+        log("Adding " + ra);
+        mRas.add(ra);
+        installNewProgramLocked();
+        return ProcessRaResult.UPDATE_NEW_RA;
+    }
+
+    /**
+     * Create an {@link ApfFilter} if {@code apfCapabilities} indicates support for packet
+     * filtering using APF programs.
+     */
+    public static ApfFilter maybeCreate(Context context, ApfConfiguration config,
+            InterfaceParams ifParams, IpClientCallbacksWrapper ipClientCallback) {
+        if (context == null || config == null || ifParams == null) return null;
+        ApfCapabilities apfCapabilities =  config.apfCapabilities;
+        if (apfCapabilities == null) return null;
+        if (apfCapabilities.apfVersionSupported == 0) return null;
+        if (apfCapabilities.maximumApfProgramSize < 512) {
+            Log.e(TAG, "Unacceptably small APF limit: " + apfCapabilities.maximumApfProgramSize);
+            return null;
+        }
+        // For now only support generating programs for Ethernet frames. If this restriction is
+        // lifted:
+        //   1. the program generator will need its offsets adjusted.
+        //   2. the packet filter attached to our packet socket will need its offset adjusted.
+        if (apfCapabilities.apfPacketFormat != ARPHRD_ETHER) return null;
+        if (!ApfGenerator.supportsVersion(apfCapabilities.apfVersionSupported)) {
+            Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported);
+            return null;
+        }
+
+        return new ApfFilter(context, config, ifParams, ipClientCallback, new IpConnectivityLog());
+    }
+
+    public synchronized void shutdown() {
+        if (mReceiveThread != null) {
+            log("shutting down");
+            mReceiveThread.halt();  // Also closes socket.
+            mReceiveThread = null;
+        }
+        mRas.clear();
+        mContext.unregisterReceiver(mDeviceIdleReceiver);
+    }
+
+    public synchronized void setMulticastFilter(boolean isEnabled) {
+        if (mMulticastFilter == isEnabled) return;
+        mMulticastFilter = isEnabled;
+        if (!isEnabled) {
+            mNumProgramUpdatesAllowingMulticast++;
+        }
+        installNewProgramLocked();
+    }
+
+    @VisibleForTesting
+    public synchronized void setDozeMode(boolean isEnabled) {
+        if (mInDozeMode == isEnabled) return;
+        mInDozeMode = isEnabled;
+        installNewProgramLocked();
+    }
+
+    /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */
+    private static LinkAddress findIPv4LinkAddress(LinkProperties lp) {
+        LinkAddress ipv4Address = null;
+        for (LinkAddress address : lp.getLinkAddresses()) {
+            if (!(address.getAddress() instanceof Inet4Address)) {
+                continue;
+            }
+            if (ipv4Address != null && !ipv4Address.isSameAddressAs(address)) {
+                // More than one IPv4 address, abort.
+                return null;
+            }
+            ipv4Address = address;
+        }
+        return ipv4Address;
+    }
+
+    public synchronized void setLinkProperties(LinkProperties lp) {
+        // NOTE: Do not keep a copy of LinkProperties as it would further duplicate state.
+        final LinkAddress ipv4Address = findIPv4LinkAddress(lp);
+        final byte[] addr = (ipv4Address != null) ? ipv4Address.getAddress().getAddress() : null;
+        final int prefix = (ipv4Address != null) ? ipv4Address.getPrefixLength() : 0;
+        if ((prefix == mIPv4PrefixLength) && Arrays.equals(addr, mIPv4Address)) {
+            return;
+        }
+        mIPv4Address = addr;
+        mIPv4PrefixLength = prefix;
+        installNewProgramLocked();
+    }
+
+    static public long counterValue(byte[] data, Counter counter)
+            throws ArrayIndexOutOfBoundsException {
+        // Follow the same wrap-around addressing scheme of the interpreter.
+        int offset = counter.offset();
+        if (offset < 0) {
+            offset = data.length + offset;
+        }
+
+        // Decode 32bit big-endian integer into a long so we can count up beyond 2^31.
+        long value = 0;
+        for (int i = 0; i < 4; i++) {
+            value = value << 8 | (data[offset] & 0xFF);
+            offset++;
+        }
+        return value;
+    }
+
+    public synchronized void dump(IndentingPrintWriter pw) {
+        pw.println("Capabilities: " + mApfCapabilities);
+        pw.println("Receive thread: " + (mReceiveThread != null ? "RUNNING" : "STOPPED"));
+        pw.println("Multicast: " + (mMulticastFilter ? "DROP" : "ALLOW"));
+        try {
+            pw.println("IPv4 address: " + InetAddress.getByAddress(mIPv4Address).getHostAddress());
+        } catch (UnknownHostException|NullPointerException e) {}
+
+        if (mLastTimeInstalledProgram == 0) {
+            pw.println("No program installed.");
+            return;
+        }
+        pw.println("Program updates: " + mNumProgramUpdates);
+        pw.println(String.format(
+                "Last program length %d, installed %ds ago, lifetime %ds",
+                mLastInstalledProgram.length, currentTimeSeconds() - mLastTimeInstalledProgram,
+                mLastInstalledProgramMinLifetime));
+
+        pw.println("RA filters:");
+        pw.increaseIndent();
+        for (Ra ra: mRas) {
+            pw.println(ra);
+            pw.increaseIndent();
+            pw.println(String.format(
+                    "Seen: %d, last %ds ago", ra.seenCount, currentTimeSeconds() - ra.mLastSeen));
+            if (DBG) {
+                pw.println("Last match:");
+                pw.increaseIndent();
+                pw.println(ra.getLastMatchingPacket());
+                pw.decreaseIndent();
+            }
+            pw.decreaseIndent();
+        }
+        pw.decreaseIndent();
+
+        if (DBG) {
+            pw.println("Last program:");
+            pw.increaseIndent();
+            pw.println(HexDump.toHexString(mLastInstalledProgram, false /* lowercase */));
+            pw.decreaseIndent();
+        }
+
+        pw.println("APF packet counters: ");
+        pw.increaseIndent();
+        if (!mApfCapabilities.hasDataAccess()) {
+            pw.println("APF counters not supported");
+        } else if (mDataSnapshot == null) {
+            pw.println("No last snapshot.");
+        } else {
+            try {
+                Counter[] counters = Counter.class.getEnumConstants();
+                for (Counter c : Arrays.asList(counters).subList(1, counters.length)) {
+                    long value = counterValue(mDataSnapshot, c);
+                    // Only print non-zero counters
+                    if (value != 0) {
+                        pw.println(c.toString() + ": " + value);
+                    }
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                pw.println("Uh-oh: " + e);
+            }
+            if (VDBG) {
+                pw.println("Raw data dump: ");
+                pw.println(HexDump.dumpHexString(mDataSnapshot));
+            }
+        }
+        pw.decreaseIndent();
+    }
+
+    // TODO: move to android.net.NetworkUtils
+    @VisibleForTesting
+    public static int ipv4BroadcastAddress(byte[] addrBytes, int prefixLength) {
+        return bytesToBEInt(addrBytes) | (int) (uint32(-1) >>> prefixLength);
+    }
+}
diff --git a/src/android/net/apf/ApfGenerator.java b/src/android/net/apf/ApfGenerator.java
new file mode 100644
index 0000000..87a1b5e
--- /dev/null
+++ b/src/android/net/apf/ApfGenerator.java
@@ -0,0 +1,937 @@
+/*
+ * 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.apf;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * APF assembler/generator.  A tool for generating an APF program.
+ *
+ * Call add*() functions to add instructions to the program, then call
+ * {@link generate} to get the APF bytecode for the program.
+ *
+ * @hide
+ */
+public class ApfGenerator {
+    /**
+     * This exception is thrown when an attempt is made to generate an illegal instruction.
+     */
+    public static class IllegalInstructionException extends Exception {
+        IllegalInstructionException(String msg) {
+            super(msg);
+        }
+    }
+    private enum Opcodes {
+        LABEL(-1),
+        LDB(1),    // Load 1 byte from immediate offset, e.g. "ldb R0, [5]"
+        LDH(2),    // Load 2 bytes from immediate offset, e.g. "ldh R0, [5]"
+        LDW(3),    // Load 4 bytes from immediate offset, e.g. "ldw R0, [5]"
+        LDBX(4),   // Load 1 byte from immediate offset plus register, e.g. "ldbx R0, [5]R0"
+        LDHX(5),   // Load 2 byte from immediate offset plus register, e.g. "ldhx R0, [5]R0"
+        LDWX(6),   // Load 4 byte from immediate offset plus register, e.g. "ldwx R0, [5]R0"
+        ADD(7),    // Add, e.g. "add R0,5"
+        MUL(8),    // Multiply, e.g. "mul R0,5"
+        DIV(9),    // Divide, e.g. "div R0,5"
+        AND(10),   // And, e.g. "and R0,5"
+        OR(11),    // Or, e.g. "or R0,5"
+        SH(12),    // Left shift, e.g, "sh R0, 5" or "sh R0, -5" (shifts right)
+        LI(13),    // Load immediate, e.g. "li R0,5" (immediate encoded as signed value)
+        JMP(14),   // Jump, e.g. "jmp label"
+        JEQ(15),   // Compare equal and branch, e.g. "jeq R0,5,label"
+        JNE(16),   // Compare not equal and branch, e.g. "jne R0,5,label"
+        JGT(17),   // Compare greater than and branch, e.g. "jgt R0,5,label"
+        JLT(18),   // Compare less than and branch, e.g. "jlt R0,5,label"
+        JSET(19),  // Compare any bits set and branch, e.g. "jset R0,5,label"
+        JNEBS(20), // Compare not equal byte sequence, e.g. "jnebs R0,5,label,0x1122334455"
+        EXT(21),   // Followed by immediate indicating ExtendedOpcodes.
+        LDDW(22),  // Load 4 bytes from data memory address (register + immediate): "lddw R0, [5]R1"
+        STDW(23);  // Store 4 bytes to data memory address (register + immediate): "stdw R0, [5]R1"
+
+        final int value;
+
+        private Opcodes(int value) {
+            this.value = value;
+        }
+    }
+    // Extended opcodes. Primary opcode is Opcodes.EXT. ExtendedOpcodes are encoded in the immediate
+    // field.
+    private enum ExtendedOpcodes {
+        LDM(0),   // Load from memory, e.g. "ldm R0,5"
+        STM(16),  // Store to memory, e.g. "stm R0,5"
+        NOT(32),  // Not, e.g. "not R0"
+        NEG(33),  // Negate, e.g. "neg R0"
+        SWAP(34), // Swap, e.g. "swap R0,R1"
+        MOVE(35);  // Move, e.g. "move R0,R1"
+
+        final int value;
+
+        private ExtendedOpcodes(int value) {
+            this.value = value;
+        }
+    }
+    public enum Register {
+        R0(0),
+        R1(1);
+
+        final int value;
+
+        private Register(int value) {
+            this.value = value;
+        }
+    }
+    private class Instruction {
+        private final byte mOpcode;   // A "Opcode" value.
+        private final byte mRegister; // A "Register" value.
+        private boolean mHasImm;
+        private byte mImmSize;
+        private boolean mImmSigned;
+        private int mImm;
+        // When mOpcode is a jump:
+        private byte mTargetLabelSize;
+        private String mTargetLabel;
+        // When mOpcode == Opcodes.LABEL:
+        private String mLabel;
+        // When mOpcode == Opcodes.JNEBS:
+        private byte[] mCompareBytes;
+        // Offset in bytes from the begining of this program. Set by {@link ApfGenerator#generate}.
+        int offset;
+
+        Instruction(Opcodes opcode, Register register) {
+            mOpcode = (byte)opcode.value;
+            mRegister = (byte)register.value;
+        }
+
+        Instruction(Opcodes opcode) {
+            this(opcode, Register.R0);
+        }
+
+        void setImm(int imm, boolean signed) {
+            mHasImm = true;
+            mImm = imm;
+            mImmSigned = signed;
+            mImmSize = calculateImmSize(imm, signed);
+        }
+
+        void setUnsignedImm(int imm) {
+            setImm(imm, false);
+        }
+
+        void setSignedImm(int imm) {
+            setImm(imm, true);
+        }
+
+        void setLabel(String label) throws IllegalInstructionException {
+            if (mLabels.containsKey(label)) {
+                throw new IllegalInstructionException("duplicate label " + label);
+            }
+            if (mOpcode != Opcodes.LABEL.value) {
+                throw new IllegalStateException("adding label to non-label instruction");
+            }
+            mLabel = label;
+            mLabels.put(label, this);
+        }
+
+        void setTargetLabel(String label) {
+            mTargetLabel = label;
+            mTargetLabelSize = 4; // May shrink later on in generate().
+        }
+
+        void setCompareBytes(byte[] bytes) {
+            if (mOpcode != Opcodes.JNEBS.value) {
+                throw new IllegalStateException("adding compare bytes to non-JNEBS instruction");
+            }
+            mCompareBytes = bytes;
+        }
+
+        /**
+         * @return size of instruction in bytes.
+         */
+        int size() {
+            if (mOpcode == Opcodes.LABEL.value) {
+                return 0;
+            }
+            int size = 1;
+            if (mHasImm) {
+                size += generatedImmSize();
+            }
+            if (mTargetLabel != null) {
+                size += generatedImmSize();
+            }
+            if (mCompareBytes != null) {
+                size += mCompareBytes.length;
+            }
+            return size;
+        }
+
+        /**
+         * Resize immediate value field so that it's only as big as required to
+         * contain the offset of the jump destination.
+         * @return {@code true} if shrunk.
+         */
+        boolean shrink() throws IllegalInstructionException {
+            if (mTargetLabel == null) {
+                return false;
+            }
+            int oldSize = size();
+            int oldTargetLabelSize = mTargetLabelSize;
+            mTargetLabelSize = calculateImmSize(calculateTargetLabelOffset(), false);
+            if (mTargetLabelSize > oldTargetLabelSize) {
+                throw new IllegalStateException("instruction grew");
+            }
+            return size() < oldSize;
+        }
+
+        /**
+         * Assemble value for instruction size field.
+         */
+        private byte generateImmSizeField() {
+            byte immSize = generatedImmSize();
+            // Encode size field to fit in 2 bits: 0->0, 1->1, 2->2, 3->4.
+            return immSize == 4 ? 3 : immSize;
+        }
+
+        /**
+         * Assemble first byte of generated instruction.
+         */
+        private byte generateInstructionByte() {
+            byte sizeField = generateImmSizeField();
+            return (byte)((mOpcode << 3) | (sizeField << 1) | mRegister);
+        }
+
+        /**
+         * Write {@code value} at offset {@code writingOffset} into {@code bytecode}.
+         * {@link generatedImmSize} bytes are written. {@code value} is truncated to
+         * {@code generatedImmSize} bytes. {@code value} is treated simply as a
+         * 32-bit value, so unsigned values should be zero extended and the truncation
+         * should simply throw away their zero-ed upper bits, and signed values should
+         * be sign extended and the truncation should simply throw away their signed
+         * upper bits.
+         */
+        private int writeValue(int value, byte[] bytecode, int writingOffset) {
+            for (int i = generatedImmSize() - 1; i >= 0; i--) {
+                bytecode[writingOffset++] = (byte)((value >> (i * 8)) & 255);
+            }
+            return writingOffset;
+        }
+
+        /**
+         * Generate bytecode for this instruction at offset {@link offset}.
+         */
+        void generate(byte[] bytecode) throws IllegalInstructionException {
+            if (mOpcode == Opcodes.LABEL.value) {
+                return;
+            }
+            int writingOffset = offset;
+            bytecode[writingOffset++] = generateInstructionByte();
+            if (mTargetLabel != null) {
+                writingOffset = writeValue(calculateTargetLabelOffset(), bytecode, writingOffset);
+            }
+            if (mHasImm) {
+                writingOffset = writeValue(mImm, bytecode, writingOffset);
+            }
+            if (mCompareBytes != null) {
+                System.arraycopy(mCompareBytes, 0, bytecode, writingOffset, mCompareBytes.length);
+                writingOffset += mCompareBytes.length;
+            }
+            if ((writingOffset - offset) != size()) {
+                throw new IllegalStateException("wrote " + (writingOffset - offset) +
+                        " but should have written " + size());
+            }
+        }
+
+        /**
+         * Calculate the size of either the immediate field or the target label field, if either is
+         * present. Most instructions have either an immediate or a target label field, but for the
+         * instructions that have both, the size of the target label field must be the same as the
+         * size of the immediate field, because there is only one length field in the instruction
+         * byte, hence why this function simply takes the maximum of the two sizes, so neither is
+         * truncated.
+         */
+        private byte generatedImmSize() {
+            return mImmSize > mTargetLabelSize ? mImmSize : mTargetLabelSize;
+        }
+
+        private int calculateTargetLabelOffset() throws IllegalInstructionException {
+            Instruction targetLabelInstruction;
+            if (mTargetLabel == DROP_LABEL) {
+                targetLabelInstruction = mDropLabel;
+            } else if (mTargetLabel == PASS_LABEL) {
+                targetLabelInstruction = mPassLabel;
+            } else {
+                targetLabelInstruction = mLabels.get(mTargetLabel);
+            }
+            if (targetLabelInstruction == null) {
+                throw new IllegalInstructionException("label not found: " + mTargetLabel);
+            }
+            // Calculate distance from end of this instruction to instruction.offset.
+            final int targetLabelOffset = targetLabelInstruction.offset - (offset + size());
+            if (targetLabelOffset < 0) {
+                throw new IllegalInstructionException("backward branches disallowed; label: " +
+                        mTargetLabel);
+            }
+            return targetLabelOffset;
+        }
+
+        private byte calculateImmSize(int imm, boolean signed) {
+            if (imm == 0) {
+                return 0;
+            }
+            if (signed && (imm >= -128 && imm <= 127) ||
+                    !signed && (imm >= 0 && imm <= 255)) {
+                return 1;
+            }
+            if (signed && (imm >= -32768 && imm <= 32767) ||
+                    !signed && (imm >= 0 && imm <= 65535)) {
+                return 2;
+            }
+            return 4;
+        }
+    }
+
+    /**
+     * Jump to this label to terminate the program and indicate the packet
+     * should be dropped.
+     */
+    public static final String DROP_LABEL = "__DROP__";
+
+    /**
+     * Jump to this label to terminate the program and indicate the packet
+     * should be passed to the AP.
+     */
+    public static final String PASS_LABEL = "__PASS__";
+
+    /**
+     * Number of memory slots available for access via APF stores to memory and loads from memory.
+     * The memory slots are numbered 0 to {@code MEMORY_SLOTS} - 1. This must be kept in sync with
+     * the APF interpreter.
+     */
+    public static final int MEMORY_SLOTS = 16;
+
+    /**
+     * Memory slot number that is prefilled with the IPv4 header length.
+     * Note that this memory slot may be overwritten by a program that
+     * executes stores to this memory slot. This must be kept in sync with
+     * the APF interpreter.
+     */
+    public static final int IPV4_HEADER_SIZE_MEMORY_SLOT = 13;
+
+    /**
+     * Memory slot number that is prefilled with the size of the packet being filtered in bytes.
+     * Note that this memory slot may be overwritten by a program that
+     * executes stores to this memory slot. This must be kept in sync with the APF interpreter.
+     */
+    public static final int PACKET_SIZE_MEMORY_SLOT = 14;
+
+    /**
+     * Memory slot number that is prefilled with the age of the filter in seconds. The age of the
+     * filter is the time since the filter was installed until now.
+     * Note that this memory slot may be overwritten by a program that
+     * executes stores to this memory slot. This must be kept in sync with the APF interpreter.
+     */
+    public static final int FILTER_AGE_MEMORY_SLOT = 15;
+
+    /**
+     * First memory slot containing prefilled values. Can be used in range comparisons to determine
+     * if memory slot index is within prefilled slots.
+     */
+    public static final int FIRST_PREFILLED_MEMORY_SLOT = IPV4_HEADER_SIZE_MEMORY_SLOT;
+
+    /**
+     * Last memory slot containing prefilled values. Can be used in range comparisons to determine
+     * if memory slot index is within prefilled slots.
+     */
+    public static final int LAST_PREFILLED_MEMORY_SLOT = FILTER_AGE_MEMORY_SLOT;
+
+    // This version number syncs up with APF_VERSION in hardware/google/apf/apf_interpreter.h
+    private static final int MIN_APF_VERSION = 2;
+
+    private final ArrayList<Instruction> mInstructions = new ArrayList<Instruction>();
+    private final HashMap<String, Instruction> mLabels = new HashMap<String, Instruction>();
+    private final Instruction mDropLabel = new Instruction(Opcodes.LABEL);
+    private final Instruction mPassLabel = new Instruction(Opcodes.LABEL);
+    private final int mVersion;
+    private boolean mGenerated;
+
+    /**
+     * Creates an ApfGenerator instance which is able to emit instructions for the specified
+     * {@code version} of the APF interpreter. Throws {@code IllegalInstructionException} if
+     * the requested version is unsupported.
+     */
+    ApfGenerator(int version) throws IllegalInstructionException {
+        mVersion = version;
+        requireApfVersion(MIN_APF_VERSION);
+    }
+
+    /**
+     * Returns true if the ApfGenerator supports the specified {@code version}, otherwise false.
+     */
+    public static boolean supportsVersion(int version) {
+        return version >= MIN_APF_VERSION;
+    }
+
+    private void requireApfVersion(int minimumVersion) throws IllegalInstructionException {
+        if (mVersion < minimumVersion) {
+            throw new IllegalInstructionException("Requires APF >= " + minimumVersion);
+        }
+    }
+
+    private void addInstruction(Instruction instruction) {
+        if (mGenerated) {
+            throw new IllegalStateException("Program already generated");
+        }
+        mInstructions.add(instruction);
+    }
+
+    /**
+     * Define a label at the current end of the program. Jumps can jump to this label. Labels are
+     * their own separate instructions, though with size 0. This facilitates having labels with
+     * no corresponding code to execute, for example a label at the end of a program. For example
+     * an {@link ApfGenerator} might be passed to a function that adds a filter like so:
+     * <pre>
+     *   load from packet
+     *   compare loaded data, jump if not equal to "next_filter"
+     *   load from packet
+     *   compare loaded data, jump if not equal to "next_filter"
+     *   jump to drop label
+     *   define "next_filter" here
+     * </pre>
+     * In this case "next_filter" may not have any generated code associated with it.
+     */
+    public ApfGenerator defineLabel(String name) throws IllegalInstructionException {
+        Instruction instruction = new Instruction(Opcodes.LABEL);
+        instruction.setLabel(name);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an unconditional jump instruction to the end of the program.
+     */
+    public ApfGenerator addJump(String target) {
+        Instruction instruction = new Instruction(Opcodes.JMP);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to load the byte at offset {@code offset}
+     * bytes from the begining of the packet into {@code register}.
+     */
+    public ApfGenerator addLoad8(Register register, int offset) {
+        Instruction instruction = new Instruction(Opcodes.LDB, register);
+        instruction.setUnsignedImm(offset);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to load 16-bits at offset {@code offset}
+     * bytes from the begining of the packet into {@code register}.
+     */
+    public ApfGenerator addLoad16(Register register, int offset) {
+        Instruction instruction = new Instruction(Opcodes.LDH, register);
+        instruction.setUnsignedImm(offset);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to load 32-bits at offset {@code offset}
+     * bytes from the begining of the packet into {@code register}.
+     */
+    public ApfGenerator addLoad32(Register register, int offset) {
+        Instruction instruction = new Instruction(Opcodes.LDW, register);
+        instruction.setUnsignedImm(offset);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to load a byte from the packet into
+     * {@code register}. The offset of the loaded byte from the begining of the packet is
+     * the sum of {@code offset} and the value in register R1.
+     */
+    public ApfGenerator addLoad8Indexed(Register register, int offset) {
+        Instruction instruction = new Instruction(Opcodes.LDBX, register);
+        instruction.setUnsignedImm(offset);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to load 16-bits from the packet into
+     * {@code register}. The offset of the loaded 16-bits from the begining of the packet is
+     * the sum of {@code offset} and the value in register R1.
+     */
+    public ApfGenerator addLoad16Indexed(Register register, int offset) {
+        Instruction instruction = new Instruction(Opcodes.LDHX, register);
+        instruction.setUnsignedImm(offset);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to load 32-bits from the packet into
+     * {@code register}. The offset of the loaded 32-bits from the begining of the packet is
+     * the sum of {@code offset} and the value in register R1.
+     */
+    public ApfGenerator addLoad32Indexed(Register register, int offset) {
+        Instruction instruction = new Instruction(Opcodes.LDWX, register);
+        instruction.setUnsignedImm(offset);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to add {@code value} to register R0.
+     */
+    public ApfGenerator addAdd(int value) {
+        Instruction instruction = new Instruction(Opcodes.ADD);
+        instruction.setSignedImm(value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to multiply register R0 by {@code value}.
+     */
+    public ApfGenerator addMul(int value) {
+        Instruction instruction = new Instruction(Opcodes.MUL);
+        instruction.setSignedImm(value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to divide register R0 by {@code value}.
+     */
+    public ApfGenerator addDiv(int value) {
+        Instruction instruction = new Instruction(Opcodes.DIV);
+        instruction.setSignedImm(value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to logically and register R0 with {@code value}.
+     */
+    public ApfGenerator addAnd(int value) {
+        Instruction instruction = new Instruction(Opcodes.AND);
+        instruction.setUnsignedImm(value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to logically or register R0 with {@code value}.
+     */
+    public ApfGenerator addOr(int value) {
+        Instruction instruction = new Instruction(Opcodes.OR);
+        instruction.setUnsignedImm(value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to shift left register R0 by {@code value} bits.
+     */
+    public ApfGenerator addLeftShift(int value) {
+        Instruction instruction = new Instruction(Opcodes.SH);
+        instruction.setSignedImm(value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to shift right register R0 by {@code value}
+     * bits.
+     */
+    public ApfGenerator addRightShift(int value) {
+        Instruction instruction = new Instruction(Opcodes.SH);
+        instruction.setSignedImm(-value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to add register R1 to register R0.
+     */
+    public ApfGenerator addAddR1() {
+        Instruction instruction = new Instruction(Opcodes.ADD, Register.R1);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to multiply register R0 by register R1.
+     */
+    public ApfGenerator addMulR1() {
+        Instruction instruction = new Instruction(Opcodes.MUL, Register.R1);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to divide register R0 by register R1.
+     */
+    public ApfGenerator addDivR1() {
+        Instruction instruction = new Instruction(Opcodes.DIV, Register.R1);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to logically and register R0 with register R1
+     * and store the result back into register R0.
+     */
+    public ApfGenerator addAndR1() {
+        Instruction instruction = new Instruction(Opcodes.AND, Register.R1);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to logically or register R0 with register R1
+     * and store the result back into register R0.
+     */
+    public ApfGenerator addOrR1() {
+        Instruction instruction = new Instruction(Opcodes.OR, Register.R1);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to shift register R0 left by the value in
+     * register R1.
+     */
+    public ApfGenerator addLeftShiftR1() {
+        Instruction instruction = new Instruction(Opcodes.SH, Register.R1);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to move {@code value} into {@code register}.
+     */
+    public ApfGenerator addLoadImmediate(Register register, int value) {
+        Instruction instruction = new Instruction(Opcodes.LI, register);
+        instruction.setSignedImm(value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value equals {@code value}.
+     */
+    public ApfGenerator addJumpIfR0Equals(int value, String target) {
+        Instruction instruction = new Instruction(Opcodes.JEQ);
+        instruction.setUnsignedImm(value);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value does not equal {@code value}.
+     */
+    public ApfGenerator addJumpIfR0NotEquals(int value, String target) {
+        Instruction instruction = new Instruction(Opcodes.JNE);
+        instruction.setUnsignedImm(value);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value is greater than {@code value}.
+     */
+    public ApfGenerator addJumpIfR0GreaterThan(int value, String target) {
+        Instruction instruction = new Instruction(Opcodes.JGT);
+        instruction.setUnsignedImm(value);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value is less than {@code value}.
+     */
+    public ApfGenerator addJumpIfR0LessThan(int value, String target) {
+        Instruction instruction = new Instruction(Opcodes.JLT);
+        instruction.setUnsignedImm(value);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value has any bits set that are also set in {@code value}.
+     */
+    public ApfGenerator addJumpIfR0AnyBitsSet(int value, String target) {
+        Instruction instruction = new Instruction(Opcodes.JSET);
+        instruction.setUnsignedImm(value);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value equals register R1's value.
+     */
+    public ApfGenerator addJumpIfR0EqualsR1(String target) {
+        Instruction instruction = new Instruction(Opcodes.JEQ, Register.R1);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value does not equal register R1's value.
+     */
+    public ApfGenerator addJumpIfR0NotEqualsR1(String target) {
+        Instruction instruction = new Instruction(Opcodes.JNE, Register.R1);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value is greater than register R1's value.
+     */
+    public ApfGenerator addJumpIfR0GreaterThanR1(String target) {
+        Instruction instruction = new Instruction(Opcodes.JGT, Register.R1);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value is less than register R1's value.
+     */
+    public ApfGenerator addJumpIfR0LessThanR1(String target) {
+        Instruction instruction = new Instruction(Opcodes.JLT, Register.R1);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if register R0's
+     * value has any bits set that are also set in R1's value.
+     */
+    public ApfGenerator addJumpIfR0AnyBitsSetR1(String target) {
+        Instruction instruction = new Instruction(Opcodes.JSET, Register.R1);
+        instruction.setTargetLabel(target);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to jump to {@code target} if the bytes of the
+     * packet at an offset specified by {@code register} match {@code bytes}.
+     */
+    public ApfGenerator addJumpIfBytesNotEqual(Register register, byte[] bytes, String target)
+            throws IllegalInstructionException {
+        if (register == Register.R1) {
+            throw new IllegalInstructionException("JNEBS fails with R1");
+        }
+        Instruction instruction = new Instruction(Opcodes.JNEBS, register);
+        instruction.setUnsignedImm(bytes.length);
+        instruction.setTargetLabel(target);
+        instruction.setCompareBytes(bytes);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to load memory slot {@code slot} into
+     * {@code register}.
+     */
+    public ApfGenerator addLoadFromMemory(Register register, int slot)
+            throws IllegalInstructionException {
+        if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
+            throw new IllegalInstructionException("illegal memory slot number: " + slot);
+        }
+        Instruction instruction = new Instruction(Opcodes.EXT, register);
+        instruction.setUnsignedImm(ExtendedOpcodes.LDM.value + slot);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to store {@code register} into memory slot
+     * {@code slot}.
+     */
+    public ApfGenerator addStoreToMemory(Register register, int slot)
+            throws IllegalInstructionException {
+        if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
+            throw new IllegalInstructionException("illegal memory slot number: " + slot);
+        }
+        Instruction instruction = new Instruction(Opcodes.EXT, register);
+        instruction.setUnsignedImm(ExtendedOpcodes.STM.value + slot);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to logically not {@code register}.
+     */
+    public ApfGenerator addNot(Register register) {
+        Instruction instruction = new Instruction(Opcodes.EXT, register);
+        instruction.setUnsignedImm(ExtendedOpcodes.NOT.value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to negate {@code register}.
+     */
+    public ApfGenerator addNeg(Register register) {
+        Instruction instruction = new Instruction(Opcodes.EXT, register);
+        instruction.setUnsignedImm(ExtendedOpcodes.NEG.value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to swap the values in register R0 and register R1.
+     */
+    public ApfGenerator addSwap() {
+        Instruction instruction = new Instruction(Opcodes.EXT);
+        instruction.setUnsignedImm(ExtendedOpcodes.SWAP.value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to move the value into
+     * {@code register} from the other register.
+     */
+    public ApfGenerator addMove(Register register) {
+        Instruction instruction = new Instruction(Opcodes.EXT, register);
+        instruction.setUnsignedImm(ExtendedOpcodes.MOVE.value);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to load 32 bits from the data memory into
+     * {@code register}. The source address is computed by adding the signed immediate
+     * @{code offset} to the other register.
+     * Requires APF v3 or greater.
+     */
+    public ApfGenerator addLoadData(Register destinationRegister, int offset)
+            throws IllegalInstructionException {
+        requireApfVersion(3);
+        Instruction instruction = new Instruction(Opcodes.LDDW, destinationRegister);
+        instruction.setSignedImm(offset);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Add an instruction to the end of the program to store 32 bits from {@code register} into the
+     * data memory. The destination address is computed by adding the signed immediate
+     * @{code offset} to the other register.
+     * Requires APF v3 or greater.
+     */
+    public ApfGenerator addStoreData(Register sourceRegister, int offset)
+            throws IllegalInstructionException {
+        requireApfVersion(3);
+        Instruction instruction = new Instruction(Opcodes.STDW, sourceRegister);
+        instruction.setSignedImm(offset);
+        addInstruction(instruction);
+        return this;
+    }
+
+    /**
+     * Updates instruction offset fields using latest instruction sizes.
+     * @return current program length in bytes.
+     */
+    private int updateInstructionOffsets() {
+        int offset = 0;
+        for (Instruction instruction : mInstructions) {
+            instruction.offset = offset;
+            offset += instruction.size();
+        }
+        return offset;
+    }
+
+    /**
+     * Returns an overestimate of the size of the generated program. {@link #generate} may return
+     * a program that is smaller.
+     */
+    public int programLengthOverEstimate() {
+        return updateInstructionOffsets();
+    }
+
+    /**
+     * Generate the bytecode for the APF program.
+     * @return the bytecode.
+     * @throws IllegalStateException if a label is referenced but not defined.
+     */
+    public byte[] generate() throws IllegalInstructionException {
+        // Enforce that we can only generate once because we cannot unshrink instructions and
+        // PASS/DROP labels may move further away requiring unshrinking if we add further
+        // instructions.
+        if (mGenerated) {
+            throw new IllegalStateException("Can only generate() once!");
+        }
+        mGenerated = true;
+        int total_size;
+        boolean shrunk;
+        // Shrink the immediate value fields of instructions.
+        // As we shrink the instructions some branch offset
+        // fields may shrink also, thereby shrinking the
+        // instructions further. Loop until we've reached the
+        // minimum size. Rarely will this loop more than a few times.
+        // Limit iterations to avoid O(n^2) behavior.
+        int iterations_remaining = 10;
+        do {
+            total_size = updateInstructionOffsets();
+            // Update drop and pass label offsets.
+            mDropLabel.offset = total_size + 1;
+            mPassLabel.offset = total_size;
+            // Limit run-time in aberant circumstances.
+            if (iterations_remaining-- == 0) break;
+            // Attempt to shrink instructions.
+            shrunk = false;
+            for (Instruction instruction : mInstructions) {
+                if (instruction.shrink()) {
+                    shrunk = true;
+                }
+            }
+        } while (shrunk);
+        // Generate bytecode for instructions.
+        byte[] bytecode = new byte[total_size];
+        for (Instruction instruction : mInstructions) {
+            instruction.generate(bytecode);
+        }
+        return bytecode;
+    }
+}
+
diff --git a/src/android/net/dhcp/DhcpAckPacket.java b/src/android/net/dhcp/DhcpAckPacket.java
new file mode 100644
index 0000000..b2eb4e2
--- /dev/null
+++ b/src/android/net/dhcp/DhcpAckPacket.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010 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;
+
+/**
+ * This class implements the DHCP-ACK packet.
+ */
+class DhcpAckPacket extends DhcpPacket {
+
+    /**
+     * The address of the server which sent this packet.
+     */
+    private final Inet4Address mSrcIp;
+
+    DhcpAckPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
+            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
+        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
+        mBroadcast = broadcast;
+        mSrcIp = serverAddress;
+    }
+
+    public String toString() {
+        String s = super.toString();
+        String dnsServers = " DNS servers: ";
+
+        for (Inet4Address dnsServer: mDnsServers) {
+            dnsServers += dnsServer.toString() + " ";
+        }
+
+        return s + " ACK: your new IP " + mYourIp +
+                ", netmask " + mSubnetMask +
+                ", gateways " + mGateways + dnsServers +
+                ", lease time " + mLeaseTime;
+    }
+
+    /**
+     * Fills in a packet with the requested ACK parameters.
+     */
+    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
+        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
+        Inet4Address destIp = mBroadcast ? INADDR_BROADCAST : mYourIp;
+        Inet4Address srcIp = mBroadcast ? INADDR_ANY : mSrcIp;
+
+        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
+            DHCP_BOOTREPLY, mBroadcast);
+        result.flip();
+        return result;
+    }
+
+    /**
+     * Adds the optional parameters to the client-generated ACK packet.
+     */
+    void finishPacket(ByteBuffer buffer) {
+        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_ACK);
+        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
+
+        addCommonServerTlvs(buffer);
+        addTlvEnd(buffer);
+    }
+
+    /**
+     * Un-boxes an Integer, returning 0 if a null reference is supplied.
+     */
+    private static final int getInt(Integer v) {
+        if (v == null) {
+            return 0;
+        } else {
+            return v.intValue();
+        }
+    }
+}
diff --git a/src/android/net/dhcp/DhcpClient.java b/src/android/net/dhcp/DhcpClient.java
new file mode 100644
index 0000000..04ac9a3
--- /dev/null
+++ b/src/android/net/dhcp/DhcpClient.java
@@ -0,0 +1,1052 @@
+/*
+ * Copyright (C) 2015 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.DhcpPacket.DHCP_BROADCAST_ADDRESS;
+import static android.net.dhcp.DhcpPacket.DHCP_DNS_SERVER;
+import static android.net.dhcp.DhcpPacket.DHCP_DOMAIN_NAME;
+import static android.net.dhcp.DhcpPacket.DHCP_LEASE_TIME;
+import static android.net.dhcp.DhcpPacket.DHCP_MTU;
+import static android.net.dhcp.DhcpPacket.DHCP_REBINDING_TIME;
+import static android.net.dhcp.DhcpPacket.DHCP_RENEWAL_TIME;
+import static android.net.dhcp.DhcpPacket.DHCP_ROUTER;
+import static android.net.dhcp.DhcpPacket.DHCP_SUBNET_MASK;
+import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO;
+import static android.net.dhcp.DhcpPacket.INADDR_ANY;
+import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
+import static android.net.util.SocketUtils.makePacketSocketAddress;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_PACKET;
+import static android.system.OsConstants.ETH_P_IP;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_RAW;
+import static android.system.OsConstants.SOL_SOCKET;
+import static android.system.OsConstants.SO_BROADCAST;
+import static android.system.OsConstants.SO_RCVBUF;
+import static android.system.OsConstants.SO_REUSEADDR;
+
+import android.content.Context;
+import android.net.DhcpResults;
+import android.net.NetworkUtils;
+import android.net.TrafficStats;
+import android.net.ip.IpClient;
+import android.net.metrics.DhcpClientEvent;
+import android.net.metrics.DhcpErrorEvent;
+import android.net.metrics.IpConnectivityLog;
+import android.net.util.InterfaceParams;
+import android.net.util.SocketUtils;
+import android.os.Message;
+import android.os.SystemClock;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.EventLog;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.util.HexDump;
+import com.android.internal.util.MessageUtils;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+import com.android.internal.util.WakeupMessage;
+
+import libcore.io.IoBridge;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * A DHCPv4 client.
+ *
+ * Written to behave similarly to the DhcpStateMachine + dhcpcd 5.5.6 combination used in Android
+ * 5.1 and below, as configured on Nexus 6. The interface is the same as DhcpStateMachine.
+ *
+ * TODO:
+ *
+ * - Exponential backoff when receiving NAKs (not specified by the RFC, but current behaviour).
+ * - Support persisting lease state and support INIT-REBOOT. Android 5.1 does this, but it does not
+ *   do so correctly: instead of requesting the lease last obtained on a particular network (e.g., a
+ *   given SSID), it requests the last-leased IP address on the same interface, causing a delay if
+ *   the server NAKs or a timeout if it doesn't.
+ *
+ * Known differences from current behaviour:
+ *
+ * - Does not request the "static routes" option.
+ * - Does not support BOOTP servers. DHCP has been around since 1993, should be everywhere now.
+ * - Requests the "broadcast" option, but does nothing with it.
+ * - Rejects invalid subnet masks such as 255.255.255.1 (current code treats that as 255.255.255.0).
+ *
+ * @hide
+ */
+public class DhcpClient extends StateMachine {
+
+    private static final String TAG = "DhcpClient";
+    private static final boolean DBG = true;
+    private static final boolean STATE_DBG = false;
+    private static final boolean MSG_DBG = false;
+    private static final boolean PACKET_DBG = false;
+
+    // Timers and timeouts.
+    private static final int SECONDS = 1000;
+    private static final int FIRST_TIMEOUT_MS   =   2 * SECONDS;
+    private static final int MAX_TIMEOUT_MS     = 128 * SECONDS;
+
+    // This is not strictly needed, since the client is asynchronous and implements exponential
+    // backoff. It's maintained for backwards compatibility with the previous DHCP code, which was
+    // a blocking operation with a 30-second timeout. We pick 36 seconds so we can send packets at
+    // t=0, t=2, t=6, t=14, t=30, allowing for 10% jitter.
+    private static final int DHCP_TIMEOUT_MS    =  36 * SECONDS;
+
+    // DhcpClient uses IpClient's handler.
+    private static final int PUBLIC_BASE = IpClient.DHCPCLIENT_CMD_BASE;
+
+    /* Commands from controller to start/stop DHCP */
+    public static final int CMD_START_DHCP                  = PUBLIC_BASE + 1;
+    public static final int CMD_STOP_DHCP                   = PUBLIC_BASE + 2;
+
+    /* Notification from DHCP state machine prior to DHCP discovery/renewal */
+    public static final int CMD_PRE_DHCP_ACTION             = PUBLIC_BASE + 3;
+    /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
+     * success/failure */
+    public static final int CMD_POST_DHCP_ACTION            = PUBLIC_BASE + 4;
+    /* Notification from DHCP state machine before quitting */
+    public static final int CMD_ON_QUIT                     = PUBLIC_BASE + 5;
+
+    /* Command from controller to indicate DHCP discovery/renewal can continue
+     * after pre DHCP action is complete */
+    public static final int CMD_PRE_DHCP_ACTION_COMPLETE    = PUBLIC_BASE + 6;
+
+    /* Command and event notification to/from IpManager requesting the setting
+     * (or clearing) of an IPv4 LinkAddress.
+     */
+    public static final int CMD_CLEAR_LINKADDRESS           = PUBLIC_BASE + 7;
+    public static final int CMD_CONFIGURE_LINKADDRESS       = PUBLIC_BASE + 8;
+    public static final int EVENT_LINKADDRESS_CONFIGURED    = PUBLIC_BASE + 9;
+
+    /* Message.arg1 arguments to CMD_POST_DHCP_ACTION notification */
+    public static final int DHCP_SUCCESS = 1;
+    public static final int DHCP_FAILURE = 2;
+
+    // Internal messages.
+    private static final int PRIVATE_BASE         = IpClient.DHCPCLIENT_CMD_BASE + 100;
+    private static final int CMD_KICK             = PRIVATE_BASE + 1;
+    private static final int CMD_RECEIVED_PACKET  = PRIVATE_BASE + 2;
+    private static final int CMD_TIMEOUT          = PRIVATE_BASE + 3;
+    private static final int CMD_RENEW_DHCP       = PRIVATE_BASE + 4;
+    private static final int CMD_REBIND_DHCP      = PRIVATE_BASE + 5;
+    private static final int CMD_EXPIRE_DHCP      = PRIVATE_BASE + 6;
+
+    // For message logging.
+    private static final Class[] sMessageClasses = { DhcpClient.class };
+    private static final SparseArray<String> sMessageNames =
+            MessageUtils.findMessageNames(sMessageClasses);
+
+    // DHCP parameters that we request.
+    /* package */ static final byte[] REQUESTED_PARAMS = new byte[] {
+        DHCP_SUBNET_MASK,
+        DHCP_ROUTER,
+        DHCP_DNS_SERVER,
+        DHCP_DOMAIN_NAME,
+        DHCP_MTU,
+        DHCP_BROADCAST_ADDRESS,  // TODO: currently ignored.
+        DHCP_LEASE_TIME,
+        DHCP_RENEWAL_TIME,
+        DHCP_REBINDING_TIME,
+        DHCP_VENDOR_INFO,
+    };
+
+    // DHCP flag that means "yes, we support unicast."
+    private static final boolean DO_UNICAST   = false;
+
+    // System services / libraries we use.
+    private final Context mContext;
+    private final Random mRandom;
+    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
+
+    // Sockets.
+    // - We use a packet socket to receive, because servers send us packets bound for IP addresses
+    //   which we have not yet configured, and the kernel protocol stack drops these.
+    // - We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can
+    //   be off-link as well as on-link).
+    private FileDescriptor mPacketSock;
+    private FileDescriptor mUdpSock;
+    private ReceiveThread mReceiveThread;
+
+    // State variables.
+    private final StateMachine mController;
+    private final WakeupMessage mKickAlarm;
+    private final WakeupMessage mTimeoutAlarm;
+    private final WakeupMessage mRenewAlarm;
+    private final WakeupMessage mRebindAlarm;
+    private final WakeupMessage mExpiryAlarm;
+    private final String mIfaceName;
+
+    private boolean mRegisteredForPreDhcpNotification;
+    private InterfaceParams mIface;
+    // TODO: MacAddress-ify more of this class hierarchy.
+    private byte[] mHwAddr;
+    private SocketAddress mInterfaceBroadcastAddr;
+    private int mTransactionId;
+    private long mTransactionStartMillis;
+    private DhcpResults mDhcpLease;
+    private long mDhcpLeaseExpiry;
+    private DhcpResults mOffer;
+
+    // Milliseconds SystemClock timestamps used to record transition times to DhcpBoundState.
+    private long mLastInitEnterTime;
+    private long mLastBoundExitTime;
+
+    // States.
+    private State mStoppedState = new StoppedState();
+    private State mDhcpState = new DhcpState();
+    private State mDhcpInitState = new DhcpInitState();
+    private State mDhcpSelectingState = new DhcpSelectingState();
+    private State mDhcpRequestingState = new DhcpRequestingState();
+    private State mDhcpHaveLeaseState = new DhcpHaveLeaseState();
+    private State mConfiguringInterfaceState = new ConfiguringInterfaceState();
+    private State mDhcpBoundState = new DhcpBoundState();
+    private State mDhcpRenewingState = new DhcpRenewingState();
+    private State mDhcpRebindingState = new DhcpRebindingState();
+    private State mDhcpInitRebootState = new DhcpInitRebootState();
+    private State mDhcpRebootingState = new DhcpRebootingState();
+    private State mWaitBeforeStartState = new WaitBeforeStartState(mDhcpInitState);
+    private State mWaitBeforeRenewalState = new WaitBeforeRenewalState(mDhcpRenewingState);
+
+    private WakeupMessage makeWakeupMessage(String cmdName, int cmd) {
+        cmdName = DhcpClient.class.getSimpleName() + "." + mIfaceName + "." + cmdName;
+        return new WakeupMessage(mContext, getHandler(), cmdName, cmd);
+    }
+
+    // TODO: Take an InterfaceParams instance instead of an interface name String.
+    private DhcpClient(Context context, StateMachine controller, String iface) {
+        super(TAG, controller.getHandler());
+
+        mContext = context;
+        mController = controller;
+        mIfaceName = iface;
+
+        addState(mStoppedState);
+        addState(mDhcpState);
+            addState(mDhcpInitState, mDhcpState);
+            addState(mWaitBeforeStartState, mDhcpState);
+            addState(mDhcpSelectingState, mDhcpState);
+            addState(mDhcpRequestingState, mDhcpState);
+            addState(mDhcpHaveLeaseState, mDhcpState);
+                addState(mConfiguringInterfaceState, mDhcpHaveLeaseState);
+                addState(mDhcpBoundState, mDhcpHaveLeaseState);
+                addState(mWaitBeforeRenewalState, mDhcpHaveLeaseState);
+                addState(mDhcpRenewingState, mDhcpHaveLeaseState);
+                addState(mDhcpRebindingState, mDhcpHaveLeaseState);
+            addState(mDhcpInitRebootState, mDhcpState);
+            addState(mDhcpRebootingState, mDhcpState);
+
+        setInitialState(mStoppedState);
+
+        mRandom = new Random();
+
+        // Used to schedule packet retransmissions.
+        mKickAlarm = makeWakeupMessage("KICK", CMD_KICK);
+        // Used to time out PacketRetransmittingStates.
+        mTimeoutAlarm = makeWakeupMessage("TIMEOUT", CMD_TIMEOUT);
+        // Used to schedule DHCP reacquisition.
+        mRenewAlarm = makeWakeupMessage("RENEW", CMD_RENEW_DHCP);
+        mRebindAlarm = makeWakeupMessage("REBIND", CMD_REBIND_DHCP);
+        mExpiryAlarm = makeWakeupMessage("EXPIRY", CMD_EXPIRE_DHCP);
+    }
+
+    public void registerForPreDhcpNotification() {
+        mRegisteredForPreDhcpNotification = true;
+    }
+
+    public static DhcpClient makeDhcpClient(
+            Context context, StateMachine controller, InterfaceParams ifParams) {
+        DhcpClient client = new DhcpClient(context, controller, ifParams.name);
+        client.mIface = ifParams;
+        client.start();
+        return client;
+    }
+
+    private boolean initInterface() {
+        if (mIface == null) mIface = InterfaceParams.getByName(mIfaceName);
+        if (mIface == null) {
+            Log.e(TAG, "Can't determine InterfaceParams for " + mIfaceName);
+            return false;
+        }
+
+        mHwAddr = mIface.macAddr.toByteArray();
+        mInterfaceBroadcastAddr = makePacketSocketAddress(mIface.index, DhcpPacket.ETHER_BROADCAST);
+        return true;
+    }
+
+    private void startNewTransaction() {
+        mTransactionId = mRandom.nextInt();
+        mTransactionStartMillis = SystemClock.elapsedRealtime();
+    }
+
+    private boolean initSockets() {
+        return initPacketSocket() && initUdpSocket();
+    }
+
+    private boolean initPacketSocket() {
+        try {
+            mPacketSock = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IP);
+            SocketAddress addr = makePacketSocketAddress((short) ETH_P_IP, mIface.index);
+            Os.bind(mPacketSock, addr);
+            NetworkUtils.attachDhcpFilter(mPacketSock);
+        } catch(SocketException|ErrnoException e) {
+            Log.e(TAG, "Error creating packet socket", e);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean initUdpSocket() {
+        final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_DHCP);
+        try {
+            mUdpSock = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+            SocketUtils.bindSocketToInterface(mUdpSock, mIfaceName);
+            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1);
+            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_BROADCAST, 1);
+            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_RCVBUF, 0);
+            Os.bind(mUdpSock, Inet4Address.ANY, DhcpPacket.DHCP_CLIENT);
+        } catch(SocketException|ErrnoException e) {
+            Log.e(TAG, "Error creating UDP socket", e);
+            return false;
+        } finally {
+            TrafficStats.setThreadStatsTag(oldTag);
+        }
+        return true;
+    }
+
+    private boolean connectUdpSock(Inet4Address to) {
+        try {
+            Os.connect(mUdpSock, to, DhcpPacket.DHCP_SERVER);
+            return true;
+        } catch (SocketException|ErrnoException e) {
+            Log.e(TAG, "Error connecting UDP socket", e);
+            return false;
+        }
+    }
+
+    private static void closeQuietly(FileDescriptor fd) {
+        try {
+            IoBridge.closeAndSignalBlockedThreads(fd);
+        } catch (IOException ignored) {}
+    }
+
+    private void closeSockets() {
+        closeQuietly(mUdpSock);
+        closeQuietly(mPacketSock);
+    }
+
+    class ReceiveThread extends Thread {
+
+        private final byte[] mPacket = new byte[DhcpPacket.MAX_LENGTH];
+        private volatile boolean mStopped = false;
+
+        public void halt() {
+            mStopped = true;
+            closeSockets();  // Interrupts the read() call the thread is blocked in.
+        }
+
+        @Override
+        public void run() {
+            if (DBG) Log.d(TAG, "Receive thread started");
+            while (!mStopped) {
+                int length = 0;  // Or compiler can't tell it's initialized if a parse error occurs.
+                try {
+                    length = Os.read(mPacketSock, mPacket, 0, mPacket.length);
+                    DhcpPacket packet = null;
+                    packet = DhcpPacket.decodeFullPacket(mPacket, length, DhcpPacket.ENCAP_L2);
+                    if (DBG) Log.d(TAG, "Received packet: " + packet);
+                    sendMessage(CMD_RECEIVED_PACKET, packet);
+                } catch (IOException|ErrnoException e) {
+                    if (!mStopped) {
+                        Log.e(TAG, "Read error", e);
+                        logError(DhcpErrorEvent.RECEIVE_ERROR);
+                    }
+                } catch (DhcpPacket.ParseException e) {
+                    Log.e(TAG, "Can't parse packet: " + e.getMessage());
+                    if (PACKET_DBG) {
+                        Log.d(TAG, HexDump.dumpHexString(mPacket, 0, length));
+                    }
+                    if (e.errorCode == DhcpErrorEvent.DHCP_NO_COOKIE) {
+                        int snetTagId = 0x534e4554;
+                        String bugId = "31850211";
+                        int uid = -1;
+                        String data = DhcpPacket.ParseException.class.getName();
+                        EventLog.writeEvent(snetTagId, bugId, uid, data);
+                    }
+                    logError(e.errorCode);
+                }
+            }
+            if (DBG) Log.d(TAG, "Receive thread stopped");
+        }
+    }
+
+    private short getSecs() {
+        return (short) ((SystemClock.elapsedRealtime() - mTransactionStartMillis) / 1000);
+    }
+
+    private boolean transmitPacket(ByteBuffer buf, String description, int encap, Inet4Address to) {
+        try {
+            if (encap == DhcpPacket.ENCAP_L2) {
+                if (DBG) Log.d(TAG, "Broadcasting " + description);
+                Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
+            } else if (encap == DhcpPacket.ENCAP_BOOTP && to.equals(INADDR_BROADCAST)) {
+                if (DBG) Log.d(TAG, "Broadcasting " + description);
+                // We only send L3-encapped broadcasts in DhcpRebindingState,
+                // where we have an IP address and an unconnected UDP socket.
+                //
+                // N.B.: We only need this codepath because DhcpRequestPacket
+                // hardcodes the source IP address to 0.0.0.0. We could reuse
+                // the packet socket if this ever changes.
+                Os.sendto(mUdpSock, buf, 0, to, DhcpPacket.DHCP_SERVER);
+            } else {
+                // It's safe to call getpeername here, because we only send unicast packets if we
+                // have an IP address, and we connect the UDP socket in DhcpBoundState#enter.
+                if (DBG) Log.d(TAG, String.format("Unicasting %s to %s",
+                        description, Os.getpeername(mUdpSock)));
+                Os.write(mUdpSock, buf);
+            }
+        } catch(ErrnoException|IOException e) {
+            Log.e(TAG, "Can't send packet: ", e);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean sendDiscoverPacket() {
+        ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
+                DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr,
+                DO_UNICAST, REQUESTED_PARAMS);
+        return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST);
+    }
+
+    private boolean sendRequestPacket(
+            Inet4Address clientAddress, Inet4Address requestedAddress,
+            Inet4Address serverAddress, Inet4Address to) {
+        // TODO: should we use the transaction ID from the server?
+        final int encap = INADDR_ANY.equals(clientAddress)
+                ? DhcpPacket.ENCAP_L2 : DhcpPacket.ENCAP_BOOTP;
+
+        ByteBuffer packet = DhcpPacket.buildRequestPacket(
+                encap, mTransactionId, getSecs(), clientAddress,
+                DO_UNICAST, mHwAddr, requestedAddress,
+                serverAddress, REQUESTED_PARAMS, null);
+        String serverStr = (serverAddress != null) ? serverAddress.getHostAddress() : null;
+        String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() +
+                             " request=" + requestedAddress.getHostAddress() +
+                             " serverid=" + serverStr;
+        return transmitPacket(packet, description, encap, to);
+    }
+
+    private void scheduleLeaseTimers() {
+        if (mDhcpLeaseExpiry == 0) {
+            Log.d(TAG, "Infinite lease, no timer scheduling needed");
+            return;
+        }
+
+        final long now = SystemClock.elapsedRealtime();
+
+        // TODO: consider getting the renew and rebind timers from T1 and T2.
+        // See also:
+        //     https://tools.ietf.org/html/rfc2131#section-4.4.5
+        //     https://tools.ietf.org/html/rfc1533#section-9.9
+        //     https://tools.ietf.org/html/rfc1533#section-9.10
+        final long remainingDelay = mDhcpLeaseExpiry - now;
+        final long renewDelay = remainingDelay / 2;
+        final long rebindDelay = remainingDelay * 7 / 8;
+        mRenewAlarm.schedule(now + renewDelay);
+        mRebindAlarm.schedule(now + rebindDelay);
+        mExpiryAlarm.schedule(now + remainingDelay);
+        Log.d(TAG, "Scheduling renewal in " + (renewDelay / 1000) + "s");
+        Log.d(TAG, "Scheduling rebind in " + (rebindDelay / 1000) + "s");
+        Log.d(TAG, "Scheduling expiry in " + (remainingDelay / 1000) + "s");
+    }
+
+    private void notifySuccess() {
+        mController.sendMessage(
+                CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
+    }
+
+    private void notifyFailure() {
+        mController.sendMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0, null);
+    }
+
+    private void acceptDhcpResults(DhcpResults results, String msg) {
+        mDhcpLease = results;
+        mOffer = null;
+        Log.d(TAG, msg + " lease: " + mDhcpLease);
+        notifySuccess();
+    }
+
+    private void clearDhcpState() {
+        mDhcpLease = null;
+        mDhcpLeaseExpiry = 0;
+        mOffer = null;
+    }
+
+    /**
+     * Quit the DhcpStateMachine.
+     *
+     * @hide
+     */
+    public void doQuit() {
+        Log.d(TAG, "doQuit");
+        quit();
+    }
+
+    @Override
+    protected void onQuitting() {
+        Log.d(TAG, "onQuitting");
+        mController.sendMessage(CMD_ON_QUIT);
+    }
+
+    abstract class LoggingState extends State {
+        private long mEnterTimeMs;
+
+        @Override
+        public void enter() {
+            if (STATE_DBG) Log.d(TAG, "Entering state " + getName());
+            mEnterTimeMs = SystemClock.elapsedRealtime();
+        }
+
+        @Override
+        public void exit() {
+            long durationMs = SystemClock.elapsedRealtime() - mEnterTimeMs;
+            logState(getName(), (int) durationMs);
+        }
+
+        private String messageName(int what) {
+            return sMessageNames.get(what, Integer.toString(what));
+        }
+
+        private String messageToString(Message message) {
+            long now = SystemClock.uptimeMillis();
+            return new StringBuilder(" ")
+                    .append(message.getWhen() - now)
+                    .append(messageName(message.what))
+                    .append(" ").append(message.arg1)
+                    .append(" ").append(message.arg2)
+                    .append(" ").append(message.obj)
+                    .toString();
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            if (MSG_DBG) {
+                Log.d(TAG, getName() + messageToString(message));
+            }
+            return NOT_HANDLED;
+        }
+
+        @Override
+        public String getName() {
+            // All DhcpClient's states are inner classes with a well defined name.
+            // Use getSimpleName() and avoid super's getName() creating new String instances.
+            return getClass().getSimpleName();
+        }
+    }
+
+    // Sends CMD_PRE_DHCP_ACTION to the controller, waits for the controller to respond with
+    // CMD_PRE_DHCP_ACTION_COMPLETE, and then transitions to mOtherState.
+    abstract class WaitBeforeOtherState extends LoggingState {
+        protected State mOtherState;
+
+        @Override
+        public void enter() {
+            super.enter();
+            mController.sendMessage(CMD_PRE_DHCP_ACTION);
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            super.processMessage(message);
+            switch (message.what) {
+                case CMD_PRE_DHCP_ACTION_COMPLETE:
+                    transitionTo(mOtherState);
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+    }
+
+    class StoppedState extends State {
+        @Override
+        public boolean processMessage(Message message) {
+            switch (message.what) {
+                case CMD_START_DHCP:
+                    if (mRegisteredForPreDhcpNotification) {
+                        transitionTo(mWaitBeforeStartState);
+                    } else {
+                        transitionTo(mDhcpInitState);
+                    }
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+    }
+
+    class WaitBeforeStartState extends WaitBeforeOtherState {
+        public WaitBeforeStartState(State otherState) {
+            super();
+            mOtherState = otherState;
+        }
+    }
+
+    class WaitBeforeRenewalState extends WaitBeforeOtherState {
+        public WaitBeforeRenewalState(State otherState) {
+            super();
+            mOtherState = otherState;
+        }
+    }
+
+    class DhcpState extends State {
+        @Override
+        public void enter() {
+            clearDhcpState();
+            if (initInterface() && initSockets()) {
+                mReceiveThread = new ReceiveThread();
+                mReceiveThread.start();
+            } else {
+                notifyFailure();
+                transitionTo(mStoppedState);
+            }
+        }
+
+        @Override
+        public void exit() {
+            if (mReceiveThread != null) {
+                mReceiveThread.halt();  // Also closes sockets.
+                mReceiveThread = null;
+            }
+            clearDhcpState();
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            super.processMessage(message);
+            switch (message.what) {
+                case CMD_STOP_DHCP:
+                    transitionTo(mStoppedState);
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+    }
+
+    public boolean isValidPacket(DhcpPacket packet) {
+        // TODO: check checksum.
+        int xid = packet.getTransactionId();
+        if (xid != mTransactionId) {
+            Log.d(TAG, "Unexpected transaction ID " + xid + ", expected " + mTransactionId);
+            return false;
+        }
+        if (!Arrays.equals(packet.getClientMac(), mHwAddr)) {
+            Log.d(TAG, "MAC addr mismatch: got " +
+                    HexDump.toHexString(packet.getClientMac()) + ", expected " +
+                    HexDump.toHexString(packet.getClientMac()));
+            return false;
+        }
+        return true;
+    }
+
+    public void setDhcpLeaseExpiry(DhcpPacket packet) {
+        long leaseTimeMillis = packet.getLeaseTimeMillis();
+        mDhcpLeaseExpiry =
+                (leaseTimeMillis > 0) ? SystemClock.elapsedRealtime() + leaseTimeMillis : 0;
+    }
+
+    /**
+     * Retransmits packets using jittered exponential backoff with an optional timeout. Packet
+     * transmission is triggered by CMD_KICK, which is sent by an AlarmManager alarm. If a subclass
+     * sets mTimeout to a positive value, then timeout() is called by an AlarmManager alarm mTimeout
+     * milliseconds after entering the state. Kicks and timeouts are cancelled when leaving the
+     * state.
+     *
+     * Concrete subclasses must implement sendPacket, which is called when the alarm fires and a
+     * packet needs to be transmitted, and receivePacket, which is triggered by CMD_RECEIVED_PACKET
+     * sent by the receive thread. They may also set mTimeout and implement timeout.
+     */
+    abstract class PacketRetransmittingState extends LoggingState {
+
+        private int mTimer;
+        protected int mTimeout = 0;
+
+        @Override
+        public void enter() {
+            super.enter();
+            initTimer();
+            maybeInitTimeout();
+            sendMessage(CMD_KICK);
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            super.processMessage(message);
+            switch (message.what) {
+                case CMD_KICK:
+                    sendPacket();
+                    scheduleKick();
+                    return HANDLED;
+                case CMD_RECEIVED_PACKET:
+                    receivePacket((DhcpPacket) message.obj);
+                    return HANDLED;
+                case CMD_TIMEOUT:
+                    timeout();
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+
+        @Override
+        public void exit() {
+            super.exit();
+            mKickAlarm.cancel();
+            mTimeoutAlarm.cancel();
+        }
+
+        abstract protected boolean sendPacket();
+        abstract protected void receivePacket(DhcpPacket packet);
+        protected void timeout() {}
+
+        protected void initTimer() {
+            mTimer = FIRST_TIMEOUT_MS;
+        }
+
+        protected int jitterTimer(int baseTimer) {
+            int maxJitter = baseTimer / 10;
+            int jitter = mRandom.nextInt(2 * maxJitter) - maxJitter;
+            return baseTimer + jitter;
+        }
+
+        protected void scheduleKick() {
+            long now = SystemClock.elapsedRealtime();
+            long timeout = jitterTimer(mTimer);
+            long alarmTime = now + timeout;
+            mKickAlarm.schedule(alarmTime);
+            mTimer *= 2;
+            if (mTimer > MAX_TIMEOUT_MS) {
+                mTimer = MAX_TIMEOUT_MS;
+            }
+        }
+
+        protected void maybeInitTimeout() {
+            if (mTimeout > 0) {
+                long alarmTime = SystemClock.elapsedRealtime() + mTimeout;
+                mTimeoutAlarm.schedule(alarmTime);
+            }
+        }
+    }
+
+    class DhcpInitState extends PacketRetransmittingState {
+        public DhcpInitState() {
+            super();
+        }
+
+        @Override
+        public void enter() {
+            super.enter();
+            startNewTransaction();
+            mLastInitEnterTime = SystemClock.elapsedRealtime();
+        }
+
+        protected boolean sendPacket() {
+            return sendDiscoverPacket();
+        }
+
+        protected void receivePacket(DhcpPacket packet) {
+            if (!isValidPacket(packet)) return;
+            if (!(packet instanceof DhcpOfferPacket)) return;
+            mOffer = packet.toDhcpResults();
+            if (mOffer != null) {
+                Log.d(TAG, "Got pending lease: " + mOffer);
+                transitionTo(mDhcpRequestingState);
+            }
+        }
+    }
+
+    // Not implemented. We request the first offer we receive.
+    class DhcpSelectingState extends LoggingState {
+    }
+
+    class DhcpRequestingState extends PacketRetransmittingState {
+        public DhcpRequestingState() {
+            mTimeout = DHCP_TIMEOUT_MS / 2;
+        }
+
+        protected boolean sendPacket() {
+            return sendRequestPacket(
+                    INADDR_ANY,                                    // ciaddr
+                    (Inet4Address) mOffer.ipAddress.getAddress(),  // DHCP_REQUESTED_IP
+                    (Inet4Address) mOffer.serverAddress,           // DHCP_SERVER_IDENTIFIER
+                    INADDR_BROADCAST);                             // packet destination address
+        }
+
+        protected void receivePacket(DhcpPacket packet) {
+            if (!isValidPacket(packet)) return;
+            if ((packet instanceof DhcpAckPacket)) {
+                DhcpResults results = packet.toDhcpResults();
+                if (results != null) {
+                    setDhcpLeaseExpiry(packet);
+                    acceptDhcpResults(results, "Confirmed");
+                    transitionTo(mConfiguringInterfaceState);
+                }
+            } else if (packet instanceof DhcpNakPacket) {
+                // TODO: Wait a while before returning into INIT state.
+                Log.d(TAG, "Received NAK, returning to INIT");
+                mOffer = null;
+                transitionTo(mDhcpInitState);
+            }
+        }
+
+        @Override
+        protected void timeout() {
+            // After sending REQUESTs unsuccessfully for a while, go back to init.
+            transitionTo(mDhcpInitState);
+        }
+    }
+
+    class DhcpHaveLeaseState extends State {
+        @Override
+        public boolean processMessage(Message message) {
+            switch (message.what) {
+                case CMD_EXPIRE_DHCP:
+                    Log.d(TAG, "Lease expired!");
+                    notifyFailure();
+                    transitionTo(mDhcpInitState);
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+
+        @Override
+        public void exit() {
+            // Clear any extant alarms.
+            mRenewAlarm.cancel();
+            mRebindAlarm.cancel();
+            mExpiryAlarm.cancel();
+            clearDhcpState();
+            // Tell IpManager to clear the IPv4 address. There is no need to
+            // wait for confirmation since any subsequent packets are sent from
+            // INADDR_ANY anyway (DISCOVER, REQUEST).
+            mController.sendMessage(CMD_CLEAR_LINKADDRESS);
+        }
+    }
+
+    class ConfiguringInterfaceState extends LoggingState {
+        @Override
+        public void enter() {
+            super.enter();
+            mController.sendMessage(CMD_CONFIGURE_LINKADDRESS, mDhcpLease.ipAddress);
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            super.processMessage(message);
+            switch (message.what) {
+                case EVENT_LINKADDRESS_CONFIGURED:
+                    transitionTo(mDhcpBoundState);
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+    }
+
+    class DhcpBoundState extends LoggingState {
+        @Override
+        public void enter() {
+            super.enter();
+            if (mDhcpLease.serverAddress != null && !connectUdpSock(mDhcpLease.serverAddress)) {
+                // There's likely no point in going into DhcpInitState here, we'll probably
+                // just repeat the transaction, get the same IP address as before, and fail.
+                //
+                // NOTE: It is observed that connectUdpSock() basically never fails, due to
+                // SO_BINDTODEVICE. Examining the local socket address shows it will happily
+                // return an IPv4 address from another interface, or even return "0.0.0.0".
+                //
+                // TODO: Consider deleting this check, following testing on several kernels.
+                notifyFailure();
+                transitionTo(mStoppedState);
+            }
+
+            scheduleLeaseTimers();
+            logTimeToBoundState();
+        }
+
+        @Override
+        public void exit() {
+            super.exit();
+            mLastBoundExitTime = SystemClock.elapsedRealtime();
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            super.processMessage(message);
+            switch (message.what) {
+                case CMD_RENEW_DHCP:
+                    if (mRegisteredForPreDhcpNotification) {
+                        transitionTo(mWaitBeforeRenewalState);
+                    } else {
+                        transitionTo(mDhcpRenewingState);
+                    }
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+
+        private void logTimeToBoundState() {
+            long now = SystemClock.elapsedRealtime();
+            if (mLastBoundExitTime > mLastInitEnterTime) {
+                logState(DhcpClientEvent.RENEWING_BOUND, (int)(now - mLastBoundExitTime));
+            } else {
+                logState(DhcpClientEvent.INITIAL_BOUND, (int)(now - mLastInitEnterTime));
+            }
+        }
+    }
+
+    abstract class DhcpReacquiringState extends PacketRetransmittingState {
+        protected String mLeaseMsg;
+
+        @Override
+        public void enter() {
+            super.enter();
+            startNewTransaction();
+        }
+
+        abstract protected Inet4Address packetDestination();
+
+        protected boolean sendPacket() {
+            return sendRequestPacket(
+                    (Inet4Address) mDhcpLease.ipAddress.getAddress(),  // ciaddr
+                    INADDR_ANY,                                        // DHCP_REQUESTED_IP
+                    null,                                              // DHCP_SERVER_IDENTIFIER
+                    packetDestination());                              // packet destination address
+        }
+
+        protected void receivePacket(DhcpPacket packet) {
+            if (!isValidPacket(packet)) return;
+            if ((packet instanceof DhcpAckPacket)) {
+                final DhcpResults results = packet.toDhcpResults();
+                if (results != null) {
+                    if (!mDhcpLease.ipAddress.equals(results.ipAddress)) {
+                        Log.d(TAG, "Renewed lease not for our current IP address!");
+                        notifyFailure();
+                        transitionTo(mDhcpInitState);
+                    }
+                    setDhcpLeaseExpiry(packet);
+                    // Updating our notion of DhcpResults here only causes the
+                    // DNS servers and routes to be updated in LinkProperties
+                    // in IpManager and by any overridden relevant handlers of
+                    // the registered IpManager.Callback.  IP address changes
+                    // are not supported here.
+                    acceptDhcpResults(results, mLeaseMsg);
+                    transitionTo(mDhcpBoundState);
+                }
+            } else if (packet instanceof DhcpNakPacket) {
+                Log.d(TAG, "Received NAK, returning to INIT");
+                notifyFailure();
+                transitionTo(mDhcpInitState);
+            }
+        }
+    }
+
+    class DhcpRenewingState extends DhcpReacquiringState {
+        public DhcpRenewingState() {
+            mLeaseMsg = "Renewed";
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            if (super.processMessage(message) == HANDLED) {
+                return HANDLED;
+            }
+
+            switch (message.what) {
+                case CMD_REBIND_DHCP:
+                    transitionTo(mDhcpRebindingState);
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+
+        @Override
+        protected Inet4Address packetDestination() {
+            // Not specifying a SERVER_IDENTIFIER option is a violation of RFC 2131, but...
+            // http://b/25343517 . Try to make things work anyway by using broadcast renews.
+            return (mDhcpLease.serverAddress != null) ?
+                    mDhcpLease.serverAddress : INADDR_BROADCAST;
+        }
+    }
+
+    class DhcpRebindingState extends DhcpReacquiringState {
+        public DhcpRebindingState() {
+            mLeaseMsg = "Rebound";
+        }
+
+        @Override
+        public void enter() {
+            super.enter();
+
+            // We need to broadcast and possibly reconnect the socket to a
+            // completely different server.
+            closeQuietly(mUdpSock);
+            if (!initUdpSocket()) {
+                Log.e(TAG, "Failed to recreate UDP socket");
+                transitionTo(mDhcpInitState);
+            }
+        }
+
+        @Override
+        protected Inet4Address packetDestination() {
+            return INADDR_BROADCAST;
+        }
+    }
+
+    class DhcpInitRebootState extends LoggingState {
+    }
+
+    class DhcpRebootingState extends LoggingState {
+    }
+
+    private void logError(int errorCode) {
+        mMetricsLog.log(mIfaceName, new DhcpErrorEvent(errorCode));
+    }
+
+    private void logState(String name, int durationMs) {
+        final DhcpClientEvent event = new DhcpClientEvent.Builder()
+                .setMsg(name)
+                .setDurationMs(durationMs)
+                .build();
+        mMetricsLog.log(mIfaceName, event);
+    }
+}
diff --git a/src/android/net/dhcp/DhcpDeclinePacket.java b/src/android/net/dhcp/DhcpDeclinePacket.java
new file mode 100644
index 0000000..7ecdea7
--- /dev/null
+++ b/src/android/net/dhcp/DhcpDeclinePacket.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 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;
+
+/**
+ * This class implements the DHCP-DECLINE packet.
+ */
+class DhcpDeclinePacket extends DhcpPacket {
+    /**
+     * Generates a DECLINE packet with the specified parameters.
+     */
+    DhcpDeclinePacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
+                      Inet4Address nextIp, Inet4Address relayIp,
+                      byte[] clientMac) {
+        super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false);
+    }
+
+    public String toString() {
+        String s = super.toString();
+        return s + " DECLINE";
+    }
+
+    /**
+     * Fills in a packet with the requested DECLINE attributes.
+     */
+    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
+        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
+
+        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
+            DHCP_BOOTREQUEST, false);
+        result.flip();
+        return result;
+    }
+
+    /**
+     * Adds optional parameters to the DECLINE packet.
+     */
+    void finishPacket(ByteBuffer buffer) {
+        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_DECLINE);
+        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
+        // RFC 2131 says we MUST NOT include our common client TLVs or the parameter request list.
+        addTlvEnd(buffer);
+    }
+}
diff --git a/src/android/net/dhcp/DhcpDiscoverPacket.java b/src/android/net/dhcp/DhcpDiscoverPacket.java
new file mode 100644
index 0000000..11f2b61
--- /dev/null
+++ b/src/android/net/dhcp/DhcpDiscoverPacket.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 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;
+
+/**
+ * This class implements the DHCP-DISCOVER packet.
+ */
+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, 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() {
+        String s = super.toString();
+        return s + " DISCOVER " +
+                (mBroadcast ? "broadcast " : "unicast ");
+    }
+
+    /**
+     * Fills in a packet with the requested DISCOVER parameters.
+     */
+    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
+        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
+        fillInPacket(encap, INADDR_BROADCAST, mSrcIp, destUdp, srcUdp, result, DHCP_BOOTREQUEST,
+                mBroadcast);
+        result.flip();
+        return result;
+    }
+
+    /**
+     * Adds optional parameters to a DISCOVER packet.
+     */
+    void finishPacket(ByteBuffer buffer) {
+        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_DISCOVER);
+        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
+        addCommonClientTlvs(buffer);
+        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
+        addTlvEnd(buffer);
+    }
+}
diff --git a/src/android/net/dhcp/DhcpInformPacket.java b/src/android/net/dhcp/DhcpInformPacket.java
new file mode 100644
index 0000000..7a83466
--- /dev/null
+++ b/src/android/net/dhcp/DhcpInformPacket.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 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;
+
+/**
+ * This class implements the (unused) DHCP-INFORM packet.
+ */
+class DhcpInformPacket extends DhcpPacket {
+    /**
+     * Generates an INFORM packet with the specified parameters.
+     */
+    DhcpInformPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
+                     Inet4Address nextIp, Inet4Address relayIp,
+                     byte[] clientMac) {
+        super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false);
+    }
+
+    public String toString() {
+        String s = super.toString();
+        return s + " INFORM";
+    }
+
+    /**
+     * Builds an INFORM packet.
+     */
+    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
+        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
+
+        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
+            DHCP_BOOTREQUEST, false);
+        result.flip();
+        return result;
+    }
+
+    /**
+     * Adds additional parameters to the INFORM packet.
+     */
+    void finishPacket(ByteBuffer buffer) {
+        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_INFORM);
+        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
+        addCommonClientTlvs(buffer);
+        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
+        addTlvEnd(buffer);
+    }
+}
diff --git a/src/android/net/dhcp/DhcpNakPacket.java b/src/android/net/dhcp/DhcpNakPacket.java
new file mode 100644
index 0000000..1da0b73
--- /dev/null
+++ b/src/android/net/dhcp/DhcpNakPacket.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 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;
+
+/**
+ * This class implements the DHCP-NAK packet.
+ */
+class DhcpNakPacket extends DhcpPacket {
+    /**
+     * Generates a NAK packet with the specified parameters.
+     */
+    DhcpNakPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
+            boolean broadcast) {
+        super(transId, secs, INADDR_ANY /* clientIp */, INADDR_ANY /* yourIp */,
+                INADDR_ANY /* nextIp */, relayIp, clientMac, broadcast);
+    }
+
+    public String toString() {
+        String s = super.toString();
+        return s + " NAK, reason " + (mMessage == null ? "(none)" : mMessage);
+    }
+
+    /**
+     * Fills in a packet with the requested NAK attributes.
+     */
+    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
+        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
+        // 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);
+        result.flip();
+        return result;
+    }
+
+    /**
+     * Adds the optional parameters to the client-generated NAK packet.
+     */
+    void finishPacket(ByteBuffer buffer) {
+        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_NAK);
+        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
+        addTlv(buffer, DHCP_MESSAGE, mMessage);
+        addTlvEnd(buffer);
+    }
+}
diff --git a/src/android/net/dhcp/DhcpOfferPacket.java b/src/android/net/dhcp/DhcpOfferPacket.java
new file mode 100644
index 0000000..0eba77e
--- /dev/null
+++ b/src/android/net/dhcp/DhcpOfferPacket.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 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;
+
+/**
+ * This class implements the DHCP-OFFER packet.
+ */
+class DhcpOfferPacket extends DhcpPacket {
+    /**
+     * The IP address of the server which sent this packet.
+     */
+    private final Inet4Address mSrcIp;
+
+    /**
+     * Generates a OFFER packet with the specified parameters.
+     */
+    DhcpOfferPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
+            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
+        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
+        mSrcIp = serverAddress;
+    }
+
+    public String toString() {
+        String s = super.toString();
+        String dnsServers = ", DNS servers: ";
+
+        if (mDnsServers != null) {
+            for (Inet4Address dnsServer: mDnsServers) {
+                dnsServers += dnsServer + " ";
+            }
+        }
+
+        return s + " OFFER, ip " + mYourIp + ", mask " + mSubnetMask +
+                dnsServers + ", gateways " + mGateways +
+                " lease time " + mLeaseTime + ", domain " + mDomainName;
+    }
+
+    /**
+     * Fills in a packet with the specified OFFER attributes.
+     */
+    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
+        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
+        Inet4Address destIp = mBroadcast ? INADDR_BROADCAST : mYourIp;
+        Inet4Address srcIp = mBroadcast ? INADDR_ANY : mSrcIp;
+
+        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
+            DHCP_BOOTREPLY, mBroadcast);
+        result.flip();
+        return result;
+    }
+
+    /**
+     * Adds the optional parameters to the server-generated OFFER packet.
+     */
+    void finishPacket(ByteBuffer buffer) {
+        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_OFFER);
+        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
+
+        addCommonServerTlvs(buffer);
+        addTlvEnd(buffer);
+    }
+}
diff --git a/src/android/net/dhcp/DhcpPacket.java b/src/android/net/dhcp/DhcpPacket.java
new file mode 100644
index 0000000..ce8b7e7
--- /dev/null
+++ b/src/android/net/dhcp/DhcpPacket.java
@@ -0,0 +1,1364 @@
+package android.net.dhcp;
+
+import android.annotation.Nullable;
+import android.net.DhcpResults;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+import android.net.metrics.DhcpErrorEvent;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.system.OsConstants;
+import android.text.TextUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.UnsupportedEncodingException;
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.ShortBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Defines basic data and operations needed to build and use packets for the
+ * DHCP protocol.  Subclasses create the specific packets used at each
+ * stage of the negotiation.
+ *
+ * @hide
+ */
+public abstract class DhcpPacket {
+    protected static final String TAG = "DhcpPacket";
+
+    // TODO: use NetworkStackConstants.IPV4_MIN_MTU once this class is moved to the network stack.
+    private static final int IPV4_MIN_MTU = 68;
+
+    // dhcpcd has a minimum lease of 20 seconds, but DhcpStateMachine would refuse to wake up the
+    // CPU for anything shorter than 5 minutes. For sanity's sake, this must be higher than the
+    // DHCP client timeout.
+    public static final int MINIMUM_LEASE = 60;
+    public static final int INFINITE_LEASE = (int) 0xffffffff;
+
+    public static final Inet4Address INADDR_ANY = (Inet4Address) Inet4Address.ANY;
+    public static final Inet4Address INADDR_BROADCAST = (Inet4Address) Inet4Address.ALL;
+    public static final byte[] ETHER_BROADCAST = new byte[] {
+            (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff,
+    };
+
+    /**
+     * Packet encapsulations.
+     */
+    public static final int ENCAP_L2 = 0;    // EthernetII header included
+    public static final int ENCAP_L3 = 1;    // IP/UDP header included
+    public static final int ENCAP_BOOTP = 2; // BOOTP contents only
+
+    /**
+     * Minimum length of a DHCP packet, excluding options, in the above encapsulations.
+     */
+    public static final int MIN_PACKET_LENGTH_BOOTP = 236;  // See diagram in RFC 2131, section 2.
+    public static final int MIN_PACKET_LENGTH_L3 = MIN_PACKET_LENGTH_BOOTP + 20 + 8;
+    public static final int MIN_PACKET_LENGTH_L2 = MIN_PACKET_LENGTH_L3 + 14;
+
+    public static final int HWADDR_LEN = 16;
+    public static final int MAX_OPTION_LEN = 255;
+
+    /**
+     * The minimum and maximum MTU that we are prepared to use. We set the minimum to the minimum
+     * IPv6 MTU because the IPv6 stack enters unusual codepaths when the link MTU drops below 1280,
+     * and does not recover if the MTU is brought above 1280 again. We set the maximum to 1500
+     * because in general it is risky to assume that the hardware is able to send/receive packets
+     * larger than 1500 bytes even if the network supports it.
+     */
+    private static final int MIN_MTU = 1280;
+    private static final int MAX_MTU = 1500;
+
+    /**
+     * IP layer definitions.
+     */
+    private static final byte IP_TYPE_UDP = (byte) 0x11;
+
+    /**
+     * IP: Version 4, Header Length 20 bytes
+     */
+    private static final byte IP_VERSION_HEADER_LEN = (byte) 0x45;
+
+    /**
+     * IP: Flags 0, Fragment Offset 0, Don't Fragment
+     */
+    private static final short IP_FLAGS_OFFSET = (short) 0x4000;
+
+    /**
+     * IP: TOS
+     */
+    private static final byte IP_TOS_LOWDELAY = (byte) 0x10;
+
+    /**
+     * IP: TTL -- use default 64 from RFC1340
+     */
+    private static final byte IP_TTL = (byte) 0x40;
+
+    /**
+     * The client DHCP port.
+     */
+    static final short DHCP_CLIENT = (short) 68;
+
+    /**
+     * The server DHCP port.
+     */
+    static final short DHCP_SERVER = (short) 67;
+
+    /**
+     * The message op code indicating a request from a client.
+     */
+    protected static final byte DHCP_BOOTREQUEST = (byte) 1;
+
+    /**
+     * The message op code indicating a response from the server.
+     */
+    protected static final byte DHCP_BOOTREPLY = (byte) 2;
+
+    /**
+     * The code type used to identify an Ethernet MAC address in the
+     * Client-ID field.
+     */
+    protected static final byte CLIENT_ID_ETHER = (byte) 1;
+
+    /**
+     * The maximum length of a packet that can be constructed.
+     */
+    protected static final int MAX_LENGTH = 1500;
+
+    /**
+     * The magic cookie that identifies this as a DHCP packet instead of BOOTP.
+     */
+    private static final int DHCP_MAGIC_COOKIE = 0x63825363;
+
+    /**
+     * DHCP Optional Type: DHCP Subnet Mask
+     */
+    protected static final byte DHCP_SUBNET_MASK = 1;
+    protected Inet4Address mSubnetMask;
+
+    /**
+     * DHCP Optional Type: DHCP Router
+     */
+    protected static final byte DHCP_ROUTER = 3;
+    protected List <Inet4Address> mGateways;
+
+    /**
+     * DHCP Optional Type: DHCP DNS Server
+     */
+    protected static final byte DHCP_DNS_SERVER = 6;
+    protected List<Inet4Address> mDnsServers;
+
+    /**
+     * DHCP Optional Type: DHCP Host Name
+     */
+    protected static final byte DHCP_HOST_NAME = 12;
+    protected String mHostName;
+
+    /**
+     * DHCP Optional Type: DHCP DOMAIN NAME
+     */
+    protected static final byte DHCP_DOMAIN_NAME = 15;
+    protected String mDomainName;
+
+    /**
+     * DHCP Optional Type: DHCP Interface MTU
+     */
+    protected static final byte DHCP_MTU = 26;
+    protected Short mMtu;
+
+    /**
+     * DHCP Optional Type: DHCP BROADCAST ADDRESS
+     */
+    protected static final byte DHCP_BROADCAST_ADDRESS = 28;
+    protected Inet4Address mBroadcastAddress;
+
+    /**
+     * DHCP Optional Type: Vendor specific information
+     */
+    protected static final byte DHCP_VENDOR_INFO = 43;
+    protected String mVendorInfo;
+
+    /**
+     * Value of the vendor specific option used to indicate that the network is metered
+     */
+    public static final String VENDOR_INFO_ANDROID_METERED = "ANDROID_METERED";
+
+    /**
+     * DHCP Optional Type: DHCP Requested IP Address
+     */
+    protected static final byte DHCP_REQUESTED_IP = 50;
+    protected Inet4Address mRequestedIp;
+
+    /**
+     * DHCP Optional Type: DHCP Lease Time
+     */
+    protected static final byte DHCP_LEASE_TIME = 51;
+    protected Integer mLeaseTime;
+
+    /**
+     * DHCP Optional Type: DHCP Message Type
+     */
+    protected static final byte DHCP_MESSAGE_TYPE = 53;
+    // the actual type values
+    protected static final byte DHCP_MESSAGE_TYPE_DISCOVER = 1;
+    protected static final byte DHCP_MESSAGE_TYPE_OFFER = 2;
+    protected static final byte DHCP_MESSAGE_TYPE_REQUEST = 3;
+    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;
+
+    /**
+     * DHCP Optional Type: DHCP Server Identifier
+     */
+    protected static final byte DHCP_SERVER_IDENTIFIER = 54;
+    protected Inet4Address mServerIdentifier;
+
+    /**
+     * DHCP Optional Type: DHCP Parameter List
+     */
+    protected static final byte DHCP_PARAMETER_LIST = 55;
+    protected byte[] mRequestedParams;
+
+    /**
+     * DHCP Optional Type: DHCP MESSAGE
+     */
+    protected static final byte DHCP_MESSAGE = 56;
+    protected String mMessage;
+
+    /**
+     * DHCP Optional Type: Maximum DHCP Message Size
+     */
+    protected static final byte DHCP_MAX_MESSAGE_SIZE = 57;
+    protected Short mMaxMessageSize;
+
+    /**
+     * DHCP Optional Type: DHCP Renewal Time Value
+     */
+    protected static final byte DHCP_RENEWAL_TIME = 58;
+    protected Integer mT1;
+
+    /**
+     * DHCP Optional Type: Rebinding Time Value
+     */
+    protected static final byte DHCP_REBINDING_TIME = 59;
+    protected Integer mT2;
+
+    /**
+     * DHCP Optional Type: Vendor Class Identifier
+     */
+    protected static final byte DHCP_VENDOR_CLASS_ID = 60;
+    protected String mVendorId;
+
+    /**
+     * DHCP Optional Type: DHCP Client Identifier
+     */
+    protected static final byte DHCP_CLIENT_IDENTIFIER = 61;
+    protected byte[] mClientId;
+
+    /**
+     * DHCP zero-length option code: pad
+     */
+    protected static final byte DHCP_OPTION_PAD = 0x00;
+
+    /**
+     * DHCP zero-length option code: end of options
+     */
+    protected static final byte DHCP_OPTION_END = (byte) 0xff;
+
+    /**
+     * The transaction identifier used in this particular DHCP negotiation
+     */
+    protected final int mTransId;
+
+    /**
+     * The seconds field in the BOOTP header. Per RFC, should be nonzero in client requests only.
+     */
+    protected final short mSecs;
+
+    /**
+     * The IP address of the client host.  This address is typically
+     * proposed by the client (from an earlier DHCP negotiation) or
+     * supplied by the server.
+     */
+    protected final Inet4Address mClientIp;
+    protected final Inet4Address mYourIp;
+    private final Inet4Address mNextIp;
+    protected final Inet4Address mRelayIp;
+
+    /**
+     * Does the client request a broadcast response?
+     */
+    protected boolean mBroadcast;
+
+    /**
+     * The six-octet MAC of the client.
+     */
+    protected final byte[] mClientMac;
+
+    /**
+     * Asks the packet object to create a ByteBuffer serialization of
+     * the packet for transmission.
+     */
+    public abstract ByteBuffer buildPacket(int encap, short destUdp,
+        short srcUdp);
+
+    /**
+     * Allows the concrete class to fill in packet-type-specific details,
+     * typically optional parameters at the end of the packet.
+     */
+    abstract void finishPacket(ByteBuffer buffer);
+
+    // Set in unit tests, to ensure that the test does not break when run on different devices and
+    // on different releases.
+    static String testOverrideVendorId = null;
+    static String testOverrideHostname = null;
+
+    protected DhcpPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
+                         Inet4Address nextIp, Inet4Address relayIp,
+                         byte[] clientMac, boolean broadcast) {
+        mTransId = transId;
+        mSecs = secs;
+        mClientIp = clientIp;
+        mYourIp = yourIp;
+        mNextIp = nextIp;
+        mRelayIp = relayIp;
+        mClientMac = clientMac;
+        mBroadcast = broadcast;
+    }
+
+    /**
+     * Returns the transaction ID.
+     */
+    public int getTransactionId() {
+        return mTransId;
+    }
+
+    /**
+     * Returns the client MAC.
+     */
+    public byte[] getClientMac() {
+        return mClientMac;
+    }
+
+    // TODO: refactor DhcpClient to set clientId when constructing packets and remove
+    // hasExplicitClientId logic
+    /**
+     * Returns whether a client ID was set in the options for this packet.
+     */
+    public boolean hasExplicitClientId() {
+        return mClientId != null;
+    }
+
+    /**
+     * Convenience method to return the client ID if it was set explicitly, or null otherwise.
+     */
+    @Nullable
+    public byte[] getExplicitClientIdOrNull() {
+        return hasExplicitClientId() ? getClientId() : 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() {
+        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;
+    }
+
+    /**
+     * Returns whether a parameter is included in the parameter request list option of this packet.
+     *
+     * <p>If there is no parameter request list option in the packet, false is returned.
+     *
+     * @param paramId ID of the parameter, such as {@link #DHCP_MTU} or {@link #DHCP_HOST_NAME}.
+     */
+    public boolean hasRequestedParam(byte paramId) {
+        if (mRequestedParams == null) {
+            return false;
+        }
+
+        for (byte reqParam : mRequestedParams) {
+            if (reqParam == paramId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Creates a new L3 packet (including IP header) containing the
+     * DHCP udp packet.  This method relies upon the delegated method
+     * finishPacket() to insert the per-packet contents.
+     */
+    protected void fillInPacket(int encap, Inet4Address destIp,
+        Inet4Address srcIp, short destUdp, short srcUdp, ByteBuffer buf,
+        byte requestCode, boolean broadcast) {
+        byte[] destIpArray = destIp.getAddress();
+        byte[] srcIpArray = srcIp.getAddress();
+        int ipHeaderOffset = 0;
+        int ipLengthOffset = 0;
+        int ipChecksumOffset = 0;
+        int endIpHeader = 0;
+        int udpHeaderOffset = 0;
+        int udpLengthOffset = 0;
+        int udpChecksumOffset = 0;
+
+        buf.clear();
+        buf.order(ByteOrder.BIG_ENDIAN);
+
+        if (encap == ENCAP_L2) {
+            buf.put(ETHER_BROADCAST);
+            buf.put(mClientMac);
+            buf.putShort((short) OsConstants.ETH_P_IP);
+        }
+
+        // if a full IP packet needs to be generated, put the IP & UDP
+        // headers in place, and pre-populate with artificial values
+        // needed to seed the IP checksum.
+        if (encap <= ENCAP_L3) {
+            ipHeaderOffset = buf.position();
+            buf.put(IP_VERSION_HEADER_LEN);
+            buf.put(IP_TOS_LOWDELAY);    // tos: IPTOS_LOWDELAY
+            ipLengthOffset = buf.position();
+            buf.putShort((short)0);  // length
+            buf.putShort((short)0);  // id
+            buf.putShort(IP_FLAGS_OFFSET); // ip offset: don't fragment
+            buf.put(IP_TTL);    // TTL: use default 64 from RFC1340
+            buf.put(IP_TYPE_UDP);
+            ipChecksumOffset = buf.position();
+            buf.putShort((short) 0); // checksum
+
+            buf.put(srcIpArray);
+            buf.put(destIpArray);
+            endIpHeader = buf.position();
+
+            // UDP header
+            udpHeaderOffset = buf.position();
+            buf.putShort(srcUdp);
+            buf.putShort(destUdp);
+            udpLengthOffset = buf.position();
+            buf.putShort((short) 0); // length
+            udpChecksumOffset = buf.position();
+            buf.putShort((short) 0); // UDP checksum -- initially zero
+        }
+
+        // DHCP payload
+        buf.put(requestCode);
+        buf.put((byte) 1); // Hardware Type: Ethernet
+        buf.put((byte) mClientMac.length); // Hardware Address Length
+        buf.put((byte) 0); // Hop Count
+        buf.putInt(mTransId);  // Transaction ID
+        buf.putShort(mSecs); // Elapsed Seconds
+
+        if (broadcast) {
+            buf.putShort((short) 0x8000); // Flags
+        } else {
+            buf.putShort((short) 0x0000); // Flags
+        }
+
+        buf.put(mClientIp.getAddress());
+        buf.put(mYourIp.getAddress());
+        buf.put(mNextIp.getAddress());
+        buf.put(mRelayIp.getAddress());
+        buf.put(mClientMac);
+        buf.position(buf.position() +
+                     (HWADDR_LEN - mClientMac.length) // pad addr to 16 bytes
+                     + 64     // empty server host name (64 bytes)
+                     + 128);  // empty boot file name (128 bytes)
+        buf.putInt(DHCP_MAGIC_COOKIE); // magic number
+        finishPacket(buf);
+
+        // round up to an even number of octets
+        if ((buf.position() & 1) == 1) {
+            buf.put((byte) 0);
+        }
+
+        // If an IP packet is being built, the IP & UDP checksums must be
+        // computed.
+        if (encap <= ENCAP_L3) {
+            // fix UDP header: insert length
+            short udpLen = (short)(buf.position() - udpHeaderOffset);
+            buf.putShort(udpLengthOffset, udpLen);
+            // fix UDP header: checksum
+            // checksum for UDP at udpChecksumOffset
+            int udpSeed = 0;
+
+            // apply IPv4 pseudo-header.  Read IP address src and destination
+            // values from the IP header and accumulate checksum.
+            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 2));
+            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 4));
+            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 6));
+            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 8));
+
+            // accumulate extra data for the pseudo-header
+            udpSeed += IP_TYPE_UDP;
+            udpSeed += udpLen;
+            // and compute UDP checksum
+            buf.putShort(udpChecksumOffset, (short) checksum(buf, udpSeed,
+                                                             udpHeaderOffset,
+                                                             buf.position()));
+            // fix IP header: insert length
+            buf.putShort(ipLengthOffset, (short)(buf.position() - ipHeaderOffset));
+            // fixup IP-header checksum
+            buf.putShort(ipChecksumOffset,
+                         (short) checksum(buf, 0, ipHeaderOffset, endIpHeader));
+        }
+    }
+
+    /**
+     * Converts a signed short value to an unsigned int value.  Needed
+     * because Java does not have unsigned types.
+     */
+    private static int intAbs(short v) {
+        return v & 0xFFFF;
+    }
+
+    /**
+     * Performs an IP checksum (used in IP header and across UDP
+     * payload) on the specified portion of a ByteBuffer.  The seed
+     * allows the checksum to commence with a specified value.
+     */
+    private int checksum(ByteBuffer buf, int seed, int start, int end) {
+        int sum = seed;
+        int bufPosition = buf.position();
+
+        // set position of original ByteBuffer, so that the ShortBuffer
+        // will be correctly initialized
+        buf.position(start);
+        ShortBuffer shortBuf = buf.asShortBuffer();
+
+        // re-set ByteBuffer position
+        buf.position(bufPosition);
+
+        short[] shortArray = new short[(end - start) / 2];
+        shortBuf.get(shortArray);
+
+        for (short s : shortArray) {
+            sum += intAbs(s);
+        }
+
+        start += shortArray.length * 2;
+
+        // see if a singleton byte remains
+        if (end != start) {
+            short b = buf.get(start);
+
+            // make it unsigned
+            if (b < 0) {
+                b += 256;
+            }
+
+            sum += b * 256;
+        }
+
+        sum = ((sum >> 16) & 0xFFFF) + (sum & 0xFFFF);
+        sum = ((sum + ((sum >> 16) & 0xFFFF)) & 0xFFFF);
+        int negated = ~sum;
+        return intAbs((short) negated);
+    }
+
+    /**
+     * Adds an optional parameter containing a single byte value.
+     */
+    protected static void addTlv(ByteBuffer buf, byte type, byte value) {
+        buf.put(type);
+        buf.put((byte) 1);
+        buf.put(value);
+    }
+
+    /**
+     * 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, @Nullable byte[] payload) {
+        if (payload != null) {
+            if (payload.length > MAX_OPTION_LEN) {
+                throw new IllegalArgumentException("DHCP option too long: "
+                        + payload.length + " vs. " + MAX_OPTION_LEN);
+            }
+            buf.put(type);
+            buf.put((byte) payload.length);
+            buf.put(payload);
+        }
+    }
+
+    /**
+     * 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, @Nullable Inet4Address addr) {
+        if (addr != null) {
+            addTlv(buf, type, addr.getAddress());
+        }
+    }
+
+    /**
+     * 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, @Nullable List<Inet4Address> addrs) {
+        if (addrs == null || addrs.size() == 0) return;
+
+        int optionLen = 4 * addrs.size();
+        if (optionLen > MAX_OPTION_LEN) {
+            throw new IllegalArgumentException("DHCP option too long: "
+                    + optionLen + " vs. " + MAX_OPTION_LEN);
+        }
+
+        buf.put(type);
+        buf.put((byte)(optionLen));
+
+        for (Inet4Address addr : addrs) {
+            buf.put(addr.getAddress());
+        }
+    }
+
+    /**
+     * 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, @Nullable Short value) {
+        if (value != null) {
+            buf.put(type);
+            buf.put((byte) 2);
+            buf.putShort(value.shortValue());
+        }
+    }
+
+    /**
+     * 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, @Nullable Integer value) {
+        if (value != null) {
+            buf.put(type);
+            buf.put((byte) 4);
+            buf.putInt(value.intValue());
+        }
+    }
+
+    /**
+     * 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, @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);
+            }
+        }
+    }
+
+    /**
+     * Adds the special end-of-optional-parameters indicator.
+     */
+    protected static void addTlvEnd(ByteBuffer buf) {
+        buf.put((byte) 0xFF);
+    }
+
+    private String getVendorId() {
+        if (testOverrideVendorId != null) return testOverrideVendorId;
+        return "android-dhcp-" + Build.VERSION.RELEASE;
+    }
+
+    private String getHostname() {
+        if (testOverrideHostname != null) return testOverrideHostname;
+        return SystemProperties.get("net.hostname");
+    }
+
+    /**
+     * Adds common client TLVs.
+     *
+     * TODO: Does this belong here? The alternative would be to modify all the buildXyzPacket
+     * methods to take them.
+     */
+    protected void addCommonClientTlvs(ByteBuffer buf) {
+        addTlv(buf, DHCP_MAX_MESSAGE_SIZE, (short) MAX_LENGTH);
+        addTlv(buf, DHCP_VENDOR_CLASS_ID, getVendorId());
+        final String hn = getHostname();
+        if (!TextUtils.isEmpty(hn)) addTlv(buf, DHCP_HOST_NAME, hn);
+    }
+
+    protected void addCommonServerTlvs(ByteBuffer buf) {
+        addTlv(buf, DHCP_LEASE_TIME, mLeaseTime);
+        if (mLeaseTime != null && mLeaseTime != INFINITE_LEASE) {
+            // The client should renew at 1/2 the lease-expiry interval
+            addTlv(buf, DHCP_RENEWAL_TIME, (int) (Integer.toUnsignedLong(mLeaseTime) / 2));
+            // Default rebinding time is set as below by RFC2131
+            addTlv(buf, DHCP_REBINDING_TIME,
+                    (int) (Integer.toUnsignedLong(mLeaseTime) * 875L / 1000L));
+        }
+        addTlv(buf, DHCP_SUBNET_MASK, mSubnetMask);
+        addTlv(buf, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
+        addTlv(buf, DHCP_ROUTER, mGateways);
+        addTlv(buf, DHCP_DNS_SERVER, mDnsServers);
+        addTlv(buf, DHCP_DOMAIN_NAME, mDomainName);
+        addTlv(buf, DHCP_HOST_NAME, mHostName);
+        addTlv(buf, DHCP_VENDOR_INFO, mVendorInfo);
+        if (mMtu != null && Short.toUnsignedInt(mMtu) >= IPV4_MIN_MTU) {
+            addTlv(buf, DHCP_MTU, mMtu);
+        }
+    }
+
+    /**
+     * Converts a MAC from an array of octets to an ASCII string.
+     */
+    public static String macToString(byte[] mac) {
+        String macAddr = "";
+
+        for (int i = 0; i < mac.length; i++) {
+            String hexString = "0" + Integer.toHexString(mac[i]);
+
+            // substring operation grabs the last 2 digits: this
+            // allows signed bytes to be converted correctly.
+            macAddr += hexString.substring(hexString.length() - 2);
+
+            if (i != (mac.length - 1)) {
+                macAddr += ":";
+            }
+        }
+
+        return macAddr;
+    }
+
+    public String toString() {
+        String macAddr = macToString(mClientMac);
+
+        return macAddr;
+    }
+
+    /**
+     * Reads a four-octet value from a ByteBuffer and construct
+     * an IPv4 address from that value.
+     */
+    private static Inet4Address readIpAddress(ByteBuffer packet) {
+        Inet4Address result = null;
+        byte[] ipAddr = new byte[4];
+        packet.get(ipAddr);
+
+        try {
+            result = (Inet4Address) Inet4Address.getByAddress(ipAddr);
+        } catch (UnknownHostException ex) {
+            // ipAddr is numeric, so this should not be
+            // triggered.  However, if it is, just nullify
+            result = null;
+        }
+
+        return result;
+    }
+
+    /**
+     * Reads a string of specified length from the buffer.
+     */
+    private static String readAsciiString(ByteBuffer buf, int byteCount, boolean nullOk) {
+        byte[] bytes = new byte[byteCount];
+        buf.get(bytes);
+        int length = bytes.length;
+        if (!nullOk) {
+            // Stop at the first null byte. This is because some DHCP options (e.g., the domain
+            // name) are passed to netd via FrameworkListener, which refuses arguments containing
+            // null bytes. We don't do this by default because vendorInfo is an opaque string which
+            // could in theory contain null bytes.
+            for (length = 0; length < bytes.length; length++) {
+                if (bytes[length] == 0) {
+                    break;
+                }
+            }
+        }
+        return new String(bytes, 0, length, StandardCharsets.US_ASCII);
+    }
+
+    private static boolean isPacketToOrFromClient(short udpSrcPort, short udpDstPort) {
+        return (udpSrcPort == DHCP_CLIENT) || (udpDstPort == DHCP_CLIENT);
+    }
+
+    private static boolean isPacketServerToServer(short udpSrcPort, short udpDstPort) {
+        return (udpSrcPort == DHCP_SERVER) && (udpDstPort == DHCP_SERVER);
+    }
+
+    public static class ParseException extends Exception {
+        public final int errorCode;
+        public ParseException(int errorCode, String msg, Object... args) {
+            super(String.format(msg, args));
+            this.errorCode = errorCode;
+        }
+    }
+
+    /**
+     * Creates a concrete DhcpPacket from the supplied ByteBuffer.  The
+     * buffer may have an L2 encapsulation (which is the full EthernetII
+     * format starting with the source-address MAC) or an L3 encapsulation
+     * (which starts with the IP header).
+     * <br>
+     * A subset of the optional parameters are parsed and are stored
+     * in object fields.
+     */
+    @VisibleForTesting
+    static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType) throws ParseException
+    {
+        // bootp parameters
+        int transactionId;
+        short secs;
+        Inet4Address clientIp;
+        Inet4Address yourIp;
+        Inet4Address nextIp;
+        Inet4Address relayIp;
+        byte[] clientMac;
+        byte[] clientId = null;
+        List<Inet4Address> dnsServers = new ArrayList<>();
+        List<Inet4Address> gateways = new ArrayList<>();  // aka router
+        Inet4Address serverIdentifier = null;
+        Inet4Address netMask = null;
+        String message = null;
+        String vendorId = null;
+        String vendorInfo = null;
+        byte[] expectedParams = null;
+        String hostName = null;
+        String domainName = null;
+        Inet4Address ipSrc = null;
+        Inet4Address ipDst = null;
+        Inet4Address bcAddr = null;
+        Inet4Address requestedIp = null;
+
+        // The following are all unsigned integers. Internally we store them as signed integers of
+        // the same length because that way we're guaranteed that they can't be out of the range of
+        // the unsigned field in the packet. Callers wanting to pass in an unsigned value will need
+        // to cast it.
+        Short mtu = null;
+        Short maxMessageSize = null;
+        Integer leaseTime = null;
+        Integer T1 = null;
+        Integer T2 = null;
+
+        // dhcp options
+        byte dhcpType = (byte) 0xFF;
+
+        packet.order(ByteOrder.BIG_ENDIAN);
+
+        // check to see if we need to parse L2, IP, and UDP encaps
+        if (pktType == ENCAP_L2) {
+            if (packet.remaining() < MIN_PACKET_LENGTH_L2) {
+                throw new ParseException(DhcpErrorEvent.L2_TOO_SHORT,
+                        "L2 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L2);
+            }
+
+            byte[] l2dst = new byte[6];
+            byte[] l2src = new byte[6];
+
+            packet.get(l2dst);
+            packet.get(l2src);
+
+            short l2type = packet.getShort();
+
+            if (l2type != OsConstants.ETH_P_IP) {
+                throw new ParseException(DhcpErrorEvent.L2_WRONG_ETH_TYPE,
+                        "Unexpected L2 type 0x%04x, expected 0x%04x", l2type, OsConstants.ETH_P_IP);
+            }
+        }
+
+        if (pktType <= ENCAP_L3) {
+            if (packet.remaining() < MIN_PACKET_LENGTH_L3) {
+                throw new ParseException(DhcpErrorEvent.L3_TOO_SHORT,
+                        "L3 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L3);
+            }
+
+            byte ipTypeAndLength = packet.get();
+            int ipVersion = (ipTypeAndLength & 0xf0) >> 4;
+            if (ipVersion != 4) {
+                throw new ParseException(
+                        DhcpErrorEvent.L3_NOT_IPV4, "Invalid IP version %d", ipVersion);
+            }
+
+            // System.out.println("ipType is " + ipType);
+            byte ipDiffServicesField = packet.get();
+            short ipTotalLength = packet.getShort();
+            short ipIdentification = packet.getShort();
+            byte ipFlags = packet.get();
+            byte ipFragOffset = packet.get();
+            byte ipTTL = packet.get();
+            byte ipProto = packet.get();
+            short ipChksm = packet.getShort();
+
+            ipSrc = readIpAddress(packet);
+            ipDst = readIpAddress(packet);
+
+            if (ipProto != IP_TYPE_UDP) {
+                throw new ParseException(
+                        DhcpErrorEvent.L4_NOT_UDP, "Protocol not UDP: %d", ipProto);
+            }
+
+            // Skip options. This cannot cause us to read beyond the end of the buffer because the
+            // IPv4 header cannot be more than (0x0f * 4) = 60 bytes long, and that is less than
+            // MIN_PACKET_LENGTH_L3.
+            int optionWords = ((ipTypeAndLength & 0x0f) - 5);
+            for (int i = 0; i < optionWords; i++) {
+                packet.getInt();
+            }
+
+            // assume UDP
+            short udpSrcPort = packet.getShort();
+            short udpDstPort = packet.getShort();
+            short udpLen = packet.getShort();
+            short udpChkSum = packet.getShort();
+
+            // Only accept packets to or from the well-known client port (expressly permitting
+            // packets from ports other than the well-known server port; http://b/24687559), and
+            // server-to-server packets, e.g. for relays.
+            if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) &&
+                !isPacketServerToServer(udpSrcPort, udpDstPort)) {
+                // This should almost never happen because we use SO_ATTACH_FILTER on the packet
+                // socket to drop packets that don't have the right source ports. However, it's
+                // possible that a packet arrives between when the socket is bound and when the
+                // filter is set. http://b/26696823 .
+                throw new ParseException(DhcpErrorEvent.L4_WRONG_PORT,
+                        "Unexpected UDP ports %d->%d", udpSrcPort, udpDstPort);
+            }
+        }
+
+        // We need to check the length even for ENCAP_L3 because the IPv4 header is variable-length.
+        if (pktType > ENCAP_BOOTP || packet.remaining() < MIN_PACKET_LENGTH_BOOTP) {
+            throw new ParseException(DhcpErrorEvent.BOOTP_TOO_SHORT,
+                        "Invalid type or BOOTP packet too short, %d < %d",
+                        packet.remaining(), MIN_PACKET_LENGTH_BOOTP);
+        }
+
+        byte type = packet.get();
+        byte hwType = packet.get();
+        int addrLen = packet.get() & 0xff;
+        byte hops = packet.get();
+        transactionId = packet.getInt();
+        secs = packet.getShort();
+        short bootpFlags = packet.getShort();
+        boolean broadcast = (bootpFlags & 0x8000) != 0;
+        byte[] ipv4addr = new byte[4];
+
+        try {
+            packet.get(ipv4addr);
+            clientIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
+            packet.get(ipv4addr);
+            yourIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
+            packet.get(ipv4addr);
+            nextIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
+            packet.get(ipv4addr);
+            relayIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
+        } catch (UnknownHostException ex) {
+            throw new ParseException(DhcpErrorEvent.L3_INVALID_IP,
+                    "Invalid IPv4 address: %s", Arrays.toString(ipv4addr));
+        }
+
+        // Some DHCP servers have been known to announce invalid client hardware address values such
+        // as 0xff. The legacy DHCP client accepted these becuause it does not check the length at
+        // all but only checks that the interface MAC address matches the first bytes of the address
+        // in the packets. We're a bit stricter: if the length is obviously invalid (i.e., bigger
+        // than the size of the field), we fudge it to 6 (Ethernet). http://b/23725795
+        // TODO: evaluate whether to make this test more liberal.
+        if (addrLen > HWADDR_LEN) {
+            addrLen = ETHER_BROADCAST.length;
+        }
+
+        clientMac = new byte[addrLen];
+        packet.get(clientMac);
+
+        // skip over address padding (16 octets allocated)
+        packet.position(packet.position() + (16 - addrLen)
+                        + 64    // skip server host name (64 chars)
+                        + 128); // skip boot file name (128 chars)
+
+        // Ensure this is a DHCP packet with a magic cookie, and not BOOTP. http://b/31850211
+        if (packet.remaining() < 4) {
+            throw new ParseException(DhcpErrorEvent.DHCP_NO_COOKIE, "not a DHCP message");
+        }
+
+        int dhcpMagicCookie = packet.getInt();
+        if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) {
+            throw new ParseException(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE,
+                    "Bad magic cookie 0x%08x, should be 0x%08x",
+                    dhcpMagicCookie, DHCP_MAGIC_COOKIE);
+        }
+
+        // parse options
+        boolean notFinishedOptions = true;
+
+        while ((packet.position() < packet.limit()) && notFinishedOptions) {
+            final byte optionType = packet.get(); // cannot underflow because position < limit
+            try {
+                if (optionType == DHCP_OPTION_END) {
+                    notFinishedOptions = false;
+                } else if (optionType == DHCP_OPTION_PAD) {
+                    // The pad option doesn't have a length field. Nothing to do.
+                } else {
+                    int optionLen = packet.get() & 0xFF;
+                    int expectedLen = 0;
+
+                    switch(optionType) {
+                        case DHCP_SUBNET_MASK:
+                            netMask = readIpAddress(packet);
+                            expectedLen = 4;
+                            break;
+                        case DHCP_ROUTER:
+                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
+                                gateways.add(readIpAddress(packet));
+                            }
+                            break;
+                        case DHCP_DNS_SERVER:
+                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
+                                dnsServers.add(readIpAddress(packet));
+                            }
+                            break;
+                        case DHCP_HOST_NAME:
+                            expectedLen = optionLen;
+                            hostName = readAsciiString(packet, optionLen, false);
+                            break;
+                        case DHCP_MTU:
+                            expectedLen = 2;
+                            mtu = packet.getShort();
+                            break;
+                        case DHCP_DOMAIN_NAME:
+                            expectedLen = optionLen;
+                            domainName = readAsciiString(packet, optionLen, false);
+                            break;
+                        case DHCP_BROADCAST_ADDRESS:
+                            bcAddr = readIpAddress(packet);
+                            expectedLen = 4;
+                            break;
+                        case DHCP_REQUESTED_IP:
+                            requestedIp = readIpAddress(packet);
+                            expectedLen = 4;
+                            break;
+                        case DHCP_LEASE_TIME:
+                            leaseTime = Integer.valueOf(packet.getInt());
+                            expectedLen = 4;
+                            break;
+                        case DHCP_MESSAGE_TYPE:
+                            dhcpType = packet.get();
+                            expectedLen = 1;
+                            break;
+                        case DHCP_SERVER_IDENTIFIER:
+                            serverIdentifier = readIpAddress(packet);
+                            expectedLen = 4;
+                            break;
+                        case DHCP_PARAMETER_LIST:
+                            expectedParams = new byte[optionLen];
+                            packet.get(expectedParams);
+                            expectedLen = optionLen;
+                            break;
+                        case DHCP_MESSAGE:
+                            expectedLen = optionLen;
+                            message = readAsciiString(packet, optionLen, false);
+                            break;
+                        case DHCP_MAX_MESSAGE_SIZE:
+                            expectedLen = 2;
+                            maxMessageSize = Short.valueOf(packet.getShort());
+                            break;
+                        case DHCP_RENEWAL_TIME:
+                            expectedLen = 4;
+                            T1 = Integer.valueOf(packet.getInt());
+                            break;
+                        case DHCP_REBINDING_TIME:
+                            expectedLen = 4;
+                            T2 = Integer.valueOf(packet.getInt());
+                            break;
+                        case DHCP_VENDOR_CLASS_ID:
+                            expectedLen = optionLen;
+                            // Embedded nulls are safe as this does not get passed to netd.
+                            vendorId = readAsciiString(packet, optionLen, true);
+                            break;
+                        case DHCP_CLIENT_IDENTIFIER: { // Client identifier
+                            byte[] id = new byte[optionLen];
+                            packet.get(id);
+                            expectedLen = optionLen;
+                        } break;
+                        case DHCP_VENDOR_INFO:
+                            expectedLen = optionLen;
+                            // Embedded nulls are safe as this does not get passed to netd.
+                            vendorInfo = readAsciiString(packet, optionLen, true);
+                            break;
+                        default:
+                            // ignore any other parameters
+                            for (int i = 0; i < optionLen; i++) {
+                                expectedLen++;
+                                byte throwaway = packet.get();
+                            }
+                    }
+
+                    if (expectedLen != optionLen) {
+                        final int errorCode = DhcpErrorEvent.errorCodeWithOption(
+                                DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH, optionType);
+                        throw new ParseException(errorCode,
+                                "Invalid length %d for option %d, expected %d",
+                                optionLen, optionType, expectedLen);
+                    }
+                }
+            } catch (BufferUnderflowException e) {
+                final int errorCode = DhcpErrorEvent.errorCodeWithOption(
+                        DhcpErrorEvent.BUFFER_UNDERFLOW, optionType);
+                throw new ParseException(errorCode, "BufferUnderflowException");
+            }
+        }
+
+        DhcpPacket newPacket;
+
+        switch(dhcpType) {
+            case (byte) 0xFF:
+                throw new ParseException(DhcpErrorEvent.DHCP_NO_MSG_TYPE,
+                        "No DHCP message type option");
+            case DHCP_MESSAGE_TYPE_DISCOVER:
+                newPacket = new DhcpDiscoverPacket(transactionId, secs, relayIp, clientMac,
+                        broadcast, ipSrc);
+                break;
+            case DHCP_MESSAGE_TYPE_OFFER:
+                newPacket = new DhcpOfferPacket(
+                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
+                break;
+            case DHCP_MESSAGE_TYPE_REQUEST:
+                newPacket = new DhcpRequestPacket(
+                    transactionId, secs, clientIp, relayIp, clientMac, broadcast);
+                break;
+            case DHCP_MESSAGE_TYPE_DECLINE:
+                newPacket = new DhcpDeclinePacket(
+                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
+                    clientMac);
+                break;
+            case DHCP_MESSAGE_TYPE_ACK:
+                newPacket = new DhcpAckPacket(
+                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
+                break;
+            case DHCP_MESSAGE_TYPE_NAK:
+                newPacket = new DhcpNakPacket(
+                        transactionId, secs, 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(
+                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
+                    clientMac);
+                break;
+            default:
+                throw new ParseException(DhcpErrorEvent.DHCP_UNKNOWN_MSG_TYPE,
+                        "Unimplemented DHCP type %d", dhcpType);
+        }
+
+        newPacket.mBroadcastAddress = bcAddr;
+        newPacket.mClientId = clientId;
+        newPacket.mDnsServers = dnsServers;
+        newPacket.mDomainName = domainName;
+        newPacket.mGateways = gateways;
+        newPacket.mHostName = hostName;
+        newPacket.mLeaseTime = leaseTime;
+        newPacket.mMessage = message;
+        newPacket.mMtu = mtu;
+        newPacket.mRequestedIp = requestedIp;
+        newPacket.mRequestedParams = expectedParams;
+        newPacket.mServerIdentifier = serverIdentifier;
+        newPacket.mSubnetMask = netMask;
+        newPacket.mMaxMessageSize = maxMessageSize;
+        newPacket.mT1 = T1;
+        newPacket.mT2 = T2;
+        newPacket.mVendorId = vendorId;
+        newPacket.mVendorInfo = vendorInfo;
+        return newPacket;
+    }
+
+    /**
+     * Parse a packet from an array of bytes, stopping at the given length.
+     */
+    public static DhcpPacket decodeFullPacket(byte[] packet, int length, int pktType)
+            throws ParseException {
+        ByteBuffer buffer = ByteBuffer.wrap(packet, 0, length).order(ByteOrder.BIG_ENDIAN);
+        try {
+            return decodeFullPacket(buffer, pktType);
+        } catch (ParseException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new ParseException(DhcpErrorEvent.PARSING_ERROR, e.getMessage());
+        }
+    }
+
+    /**
+     *  Construct a DhcpResults object from a DHCP reply packet.
+     */
+    public DhcpResults toDhcpResults() {
+        Inet4Address ipAddress = mYourIp;
+        if (ipAddress.equals(Inet4Address.ANY)) {
+            ipAddress = mClientIp;
+            if (ipAddress.equals(Inet4Address.ANY)) {
+                return null;
+            }
+        }
+
+        int prefixLength;
+        if (mSubnetMask != null) {
+            try {
+                prefixLength = NetworkUtils.netmaskToPrefixLength(mSubnetMask);
+            } catch (IllegalArgumentException e) {
+                // Non-contiguous netmask.
+                return null;
+            }
+        } else {
+            prefixLength = NetworkUtils.getImplicitNetmask(ipAddress);
+        }
+
+        DhcpResults results = new DhcpResults();
+        try {
+            results.ipAddress = new LinkAddress(ipAddress, prefixLength);
+        } catch (IllegalArgumentException e) {
+            return null;
+        }
+
+        if (mGateways.size() > 0) {
+            results.gateway = mGateways.get(0);
+        }
+
+        results.dnsServers.addAll(mDnsServers);
+        results.domains = mDomainName;
+        results.serverAddress = mServerIdentifier;
+        results.vendorInfo = mVendorInfo;
+        results.leaseDuration = (mLeaseTime != null) ? mLeaseTime : INFINITE_LEASE;
+        results.mtu = (mMtu != null && MIN_MTU <= mMtu && mMtu <= MAX_MTU) ? mMtu : 0;
+
+        return results;
+    }
+
+    /**
+     * Returns the parsed lease time, in milliseconds, or 0 for infinite.
+     */
+    public long getLeaseTimeMillis() {
+        // dhcpcd treats the lack of a lease time option as an infinite lease.
+        if (mLeaseTime == null || mLeaseTime == INFINITE_LEASE) {
+            return 0;
+        } else if (0 <= mLeaseTime && mLeaseTime < MINIMUM_LEASE) {
+            return MINIMUM_LEASE * 1000;
+        } else {
+            return (mLeaseTime & 0xffffffffL) * 1000;
+        }
+    }
+
+    /**
+     * Builds a DHCP-DISCOVER packet from the required specified
+     * parameters.
+     */
+    public static ByteBuffer buildDiscoverPacket(int encap, int transactionId,
+        short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams) {
+        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);
+    }
+
+    /**
+     * Builds a DHCP-OFFER packet from the required specified
+     * parameters.
+     */
+    public static ByteBuffer buildOfferPacket(int encap, int transactionId,
+        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp,
+        Inet4Address yourIp, byte[] mac, Integer timeout, Inet4Address netMask,
+        Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
+        Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
+        short mtu) {
+        DhcpPacket pkt = new DhcpOfferPacket(
+                transactionId, (short) 0, broadcast, serverIpAddr, relayIp,
+                INADDR_ANY /* clientIp */, yourIp, mac);
+        pkt.mGateways = gateways;
+        pkt.mDnsServers = dnsServers;
+        pkt.mLeaseTime = timeout;
+        pkt.mDomainName = domainName;
+        pkt.mHostName = hostname;
+        pkt.mServerIdentifier = dhcpServerIdentifier;
+        pkt.mSubnetMask = netMask;
+        pkt.mBroadcastAddress = bcAddr;
+        pkt.mMtu = mtu;
+        if (metered) {
+            pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED;
+        }
+        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
+    }
+
+    /**
+     * Builds a DHCP-ACK packet from the required specified parameters.
+     */
+    public static ByteBuffer buildAckPacket(int encap, int transactionId,
+        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp, Inet4Address yourIp,
+        Inet4Address requestClientIp, byte[] mac, Integer timeout, Inet4Address netMask,
+        Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
+        Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
+        short mtu) {
+        DhcpPacket pkt = new DhcpAckPacket(
+                transactionId, (short) 0, broadcast, serverIpAddr, relayIp, requestClientIp, yourIp,
+                mac);
+        pkt.mGateways = gateways;
+        pkt.mDnsServers = dnsServers;
+        pkt.mLeaseTime = timeout;
+        pkt.mDomainName = domainName;
+        pkt.mHostName = hostname;
+        pkt.mSubnetMask = netMask;
+        pkt.mServerIdentifier = dhcpServerIdentifier;
+        pkt.mBroadcastAddress = bcAddr;
+        pkt.mMtu = mtu;
+        if (metered) {
+            pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED;
+        }
+        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
+    }
+
+    /**
+     * Builds a DHCP-NAK packet from the required specified parameters.
+     */
+    public static ByteBuffer buildNakPacket(int encap, int transactionId, Inet4Address serverIpAddr,
+            Inet4Address relayIp, byte[] mac, boolean broadcast, String message) {
+        DhcpPacket pkt = new DhcpNakPacket(
+                transactionId, (short) 0, relayIp, mac, broadcast);
+        pkt.mMessage = message;
+        pkt.mServerIdentifier = serverIpAddr;
+        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
+    }
+
+    /**
+     * Builds a DHCP-REQUEST packet from the required specified parameters.
+     */
+    public static ByteBuffer buildRequestPacket(int encap,
+        int transactionId, short secs, Inet4Address clientIp, boolean broadcast,
+        byte[] clientMac, Inet4Address requestedIpAddress,
+        Inet4Address serverIdentifier, byte[] requestedParams, String hostName) {
+        DhcpPacket pkt = new DhcpRequestPacket(transactionId, secs, clientIp,
+                INADDR_ANY /* relayIp */, clientMac, broadcast);
+        pkt.mRequestedIp = requestedIpAddress;
+        pkt.mServerIdentifier = serverIdentifier;
+        pkt.mHostName = hostName;
+        pkt.mRequestedParams = requestedParams;
+        ByteBuffer result = pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT);
+        return result;
+    }
+}
diff --git a/src/android/net/dhcp/DhcpReleasePacket.java b/src/android/net/dhcp/DhcpReleasePacket.java
new file mode 100644
index 0000000..3958303
--- /dev/null
+++ b/src/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/src/android/net/dhcp/DhcpRequestPacket.java b/src/android/net/dhcp/DhcpRequestPacket.java
new file mode 100644
index 0000000..231d045
--- /dev/null
+++ b/src/android/net/dhcp/DhcpRequestPacket.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 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.util.Log;
+
+import java.net.Inet4Address;
+import java.nio.ByteBuffer;
+
+/**
+ * This class implements the DHCP-REQUEST packet.
+ */
+class DhcpRequestPacket extends DhcpPacket {
+    /**
+     * Generates a REQUEST packet with the specified parameters.
+     */
+    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() {
+        String s = super.toString();
+        return s + " REQUEST, desired IP " + mRequestedIp + " from host '"
+            + mHostName + "', param list length "
+            + (mRequestedParams == null ? 0 : mRequestedParams.length);
+    }
+
+    /**
+     * Fills in a packet with the requested REQUEST attributes.
+     */
+    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);
+        result.flip();
+        return result;
+    }
+
+    /**
+     * Adds the optional parameters to the client-generated REQUEST packet.
+     */
+    void finishPacket(ByteBuffer buffer) {
+        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_REQUEST);
+        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
+        if (!INADDR_ANY.equals(mRequestedIp)) {
+            addTlv(buffer, DHCP_REQUESTED_IP, mRequestedIp);
+        }
+        if (!INADDR_ANY.equals(mServerIdentifier)) {
+            addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
+        }
+        addCommonClientTlvs(buffer);
+        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
+        addTlvEnd(buffer);
+    }
+}
diff --git a/src/android/net/ip/ConnectivityPacketTracker.java b/src/android/net/ip/ConnectivityPacketTracker.java
new file mode 100644
index 0000000..385dd52
--- /dev/null
+++ b/src/android/net/ip/ConnectivityPacketTracker.java
@@ -0,0 +1,153 @@
+/*
+ * 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.ip;
+
+import static android.net.util.SocketUtils.makePacketSocketAddress;
+import static android.system.OsConstants.AF_PACKET;
+import static android.system.OsConstants.ARPHRD_ETHER;
+import static android.system.OsConstants.ETH_P_ALL;
+import static android.system.OsConstants.SOCK_RAW;
+
+import android.net.NetworkUtils;
+import android.net.util.ConnectivityPacketSummary;
+import android.net.util.InterfaceParams;
+import android.net.util.PacketReader;
+import android.os.Handler;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.Log;
+
+import libcore.util.HexEncoding;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+
+/**
+ * Critical connectivity packet tracking daemon.
+ *
+ * Tracks ARP, DHCPv4, and IPv6 RS/RA/NS/NA packets.
+ *
+ * This class's constructor, start() and stop() methods must only be called
+ * from the same thread on which the passed in |log| is accessed.
+ *
+ * Log lines include a hexdump of the packet, which can be decoded via:
+ *
+ *     echo -n H3XSTR1NG | sed -e 's/\([0-9A-F][0-9A-F]\)/\1 /g' -e 's/^/000000 /'
+ *                       | text2pcap - -
+ *                       | tcpdump -n -vv -e -r -
+ *
+ * @hide
+ */
+public class ConnectivityPacketTracker {
+    private static final String TAG = ConnectivityPacketTracker.class.getSimpleName();
+    private static final boolean DBG = false;
+    private static final String MARK_START = "--- START ---";
+    private static final String MARK_STOP = "--- STOP ---";
+    private static final String MARK_NAMED_START = "--- START (%s) ---";
+    private static final String MARK_NAMED_STOP = "--- STOP (%s) ---";
+
+    private final String mTag;
+    private final LocalLog mLog;
+    private final PacketReader mPacketListener;
+    private boolean mRunning;
+    private String mDisplayName;
+
+    public ConnectivityPacketTracker(Handler h, InterfaceParams ifParams, LocalLog log) {
+        if (ifParams == null) throw new IllegalArgumentException("null InterfaceParams");
+
+        mTag = TAG + "." + ifParams.name;
+        mLog = log;
+        mPacketListener = new PacketListener(h, ifParams);
+    }
+
+    public void start(String displayName) {
+        mRunning = true;
+        mDisplayName = displayName;
+        mPacketListener.start();
+    }
+
+    public void stop() {
+        mPacketListener.stop();
+        mRunning = false;
+        mDisplayName = null;
+    }
+
+    private final class PacketListener extends PacketReader {
+        private final InterfaceParams mInterface;
+
+        PacketListener(Handler h, InterfaceParams ifParams) {
+            super(h, ifParams.defaultMtu);
+            mInterface = ifParams;
+        }
+
+        @Override
+        protected FileDescriptor createFd() {
+            FileDescriptor s = null;
+            try {
+                s = Os.socket(AF_PACKET, SOCK_RAW, 0);
+                NetworkUtils.attachControlPacketFilter(s, ARPHRD_ETHER);
+                Os.bind(s, makePacketSocketAddress((short) ETH_P_ALL, mInterface.index));
+            } catch (ErrnoException | IOException e) {
+                logError("Failed to create packet tracking socket: ", e);
+                closeFd(s);
+                return null;
+            }
+            return s;
+        }
+
+        @Override
+        protected void handlePacket(byte[] recvbuf, int length) {
+            final String summary = ConnectivityPacketSummary.summarize(
+                    mInterface.macAddr, recvbuf, length);
+            if (summary == null) return;
+
+            if (DBG) Log.d(mTag, summary);
+            addLogEntry(summary +
+                        "\n[" + new String(HexEncoding.encode(recvbuf, 0, length)) + "]");
+        }
+
+        @Override
+        protected void onStart() {
+            final String msg = TextUtils.isEmpty(mDisplayName)
+                    ? MARK_START
+                    : String.format(MARK_NAMED_START, mDisplayName);
+            mLog.log(msg);
+        }
+
+        @Override
+        protected void onStop() {
+            String msg = TextUtils.isEmpty(mDisplayName)
+                    ? MARK_STOP
+                    : String.format(MARK_NAMED_STOP, mDisplayName);
+            if (!mRunning) msg += " (packet listener stopped unexpectedly)";
+            mLog.log(msg);
+        }
+
+        @Override
+        protected void logError(String msg, Exception e) {
+            Log.e(mTag, msg, e);
+            addLogEntry(msg + e);
+        }
+
+        private void addLogEntry(String entry) {
+            mLog.log(entry);
+        }
+    }
+}
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
new file mode 100644
index 0000000..ad7f85d
--- /dev/null
+++ b/src/android/net/ip/IpClient.java
@@ -0,0 +1,1691 @@
+/*
+ * Copyright (C) 2017 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.ip;
+
+import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
+import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable;
+import static android.net.shared.LinkPropertiesParcelableUtil.toStableParcelable;
+
+import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.DhcpResults;
+import android.net.INetd;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.ProvisioningConfigurationParcelable;
+import android.net.ProxyInfo;
+import android.net.ProxyInfoParcelable;
+import android.net.RouteInfo;
+import android.net.apf.ApfCapabilities;
+import android.net.apf.ApfFilter;
+import android.net.dhcp.DhcpClient;
+import android.net.ip.IIpClientCallbacks;
+import android.net.metrics.IpConnectivityLog;
+import android.net.metrics.IpManagerEvent;
+import android.net.shared.InitialConfiguration;
+import android.net.shared.NetdService;
+import android.net.shared.ProvisioningConfiguration;
+import android.net.util.InterfaceParams;
+import android.net.util.SharedLog;
+import android.os.ConditionVariable;
+import android.os.INetworkManagementService;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IState;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.MessageUtils;
+import com.android.internal.util.Preconditions;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+import com.android.internal.util.WakeupMessage;
+import com.android.server.net.NetlinkTracker;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+
+/**
+ * IpClient
+ *
+ * This class provides the interface to IP-layer provisioning and maintenance
+ * functionality that can be used by transport layers like Wi-Fi, Ethernet,
+ * et cetera.
+ *
+ * [ Lifetime ]
+ * IpClient is designed to be instantiated as soon as the interface name is
+ * known and can be as long-lived as the class containing it (i.e. declaring
+ * it "private final" is okay).
+ *
+ * @hide
+ */
+public class IpClient extends StateMachine {
+    private static final boolean DBG = false;
+
+    // For message logging.
+    private static final Class[] sMessageClasses = { IpClient.class, DhcpClient.class };
+    private static final SparseArray<String> sWhatToString =
+            MessageUtils.findMessageNames(sMessageClasses);
+    // Two static concurrent hashmaps of interface name to logging classes.
+    // One holds StateMachine logs and the other connectivity packet logs.
+    private static final ConcurrentHashMap<String, SharedLog> sSmLogs = new ConcurrentHashMap<>();
+    private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>();
+
+    /**
+     * Dump all state machine and connectivity packet logs to the specified writer.
+     * @param skippedIfaces Interfaces for which logs should not be dumped.
+     */
+    public static void dumpAllLogs(PrintWriter writer, Set<String> skippedIfaces) {
+        for (String ifname : sSmLogs.keySet()) {
+            if (skippedIfaces.contains(ifname)) continue;
+
+            writer.println(String.format("--- BEGIN %s ---", ifname));
+
+            final SharedLog smLog = sSmLogs.get(ifname);
+            if (smLog != null) {
+                writer.println("State machine log:");
+                smLog.dump(null, writer, null);
+            }
+
+            writer.println("");
+
+            final LocalLog pktLog = sPktLogs.get(ifname);
+            if (pktLog != null) {
+                writer.println("Connectivity packet log:");
+                pktLog.readOnlyLocalLog().dump(null, writer, null);
+            }
+
+            writer.println(String.format("--- END %s ---", ifname));
+        }
+    }
+
+    // Use a wrapper class to log in order to ensure complete and detailed
+    // logging. This method is lighter weight than annotations/reflection
+    // and has the following benefits:
+    //
+    //     - No invoked method can be forgotten.
+    //       Any new method added to IpClient.Callback must be overridden
+    //       here or it will never be called.
+    //
+    //     - No invoking call site can be forgotten.
+    //       Centralized logging in this way means call sites don't need to
+    //       remember to log, and therefore no call site can be forgotten.
+    //
+    //     - No variation in log format among call sites.
+    //       Encourages logging of any available arguments, and all call sites
+    //       are necessarily logged identically.
+    //
+    // NOTE: Log first because passed objects may or may not be thread-safe and
+    // once passed on to the callback they may be modified by another thread.
+    //
+    // TODO: Find an lighter weight approach.
+    public static class IpClientCallbacksWrapper {
+        private static final String PREFIX = "INVOKE ";
+        private final IIpClientCallbacks mCallback;
+        private final SharedLog mLog;
+
+        @VisibleForTesting
+        protected IpClientCallbacksWrapper(IIpClientCallbacks callback, SharedLog log) {
+            mCallback = callback;
+            mLog = log;
+        }
+
+        private void log(String msg) {
+            mLog.log(PREFIX + msg);
+        }
+
+        private void log(String msg, Throwable e) {
+            mLog.e(PREFIX + msg, e);
+        }
+
+        public void onPreDhcpAction() {
+            log("onPreDhcpAction()");
+            try {
+                mCallback.onPreDhcpAction();
+            } catch (RemoteException e) {
+                log("Failed to call onPreDhcpAction", e);
+            }
+        }
+
+        public void onPostDhcpAction() {
+            log("onPostDhcpAction()");
+            try {
+                mCallback.onPostDhcpAction();
+            } catch (RemoteException e) {
+                log("Failed to call onPostDhcpAction", e);
+            }
+        }
+
+        public void onNewDhcpResults(DhcpResults dhcpResults) {
+            log("onNewDhcpResults({" + dhcpResults + "})");
+            try {
+                mCallback.onNewDhcpResults(toStableParcelable(dhcpResults));
+            } catch (RemoteException e) {
+                log("Failed to call onNewDhcpResults", e);
+            }
+        }
+
+        public void onProvisioningSuccess(LinkProperties newLp) {
+            log("onProvisioningSuccess({" + newLp + "})");
+            try {
+                mCallback.onProvisioningSuccess(toStableParcelable(newLp));
+            } catch (RemoteException e) {
+                log("Failed to call onProvisioningSuccess", e);
+            }
+        }
+
+        public void onProvisioningFailure(LinkProperties newLp) {
+            log("onProvisioningFailure({" + newLp + "})");
+            try {
+                mCallback.onProvisioningFailure(toStableParcelable(newLp));
+            } catch (RemoteException e) {
+                log("Failed to call onProvisioningFailure", e);
+            }
+        }
+
+        public void onLinkPropertiesChange(LinkProperties newLp) {
+            log("onLinkPropertiesChange({" + newLp + "})");
+            try {
+                mCallback.onLinkPropertiesChange(toStableParcelable(newLp));
+            } catch (RemoteException e) {
+                log("Failed to call onLinkPropertiesChange", e);
+            }
+        }
+
+        public void onReachabilityLost(String logMsg) {
+            log("onReachabilityLost(" + logMsg + ")");
+            try {
+                mCallback.onReachabilityLost(logMsg);
+            } catch (RemoteException e) {
+                log("Failed to call onReachabilityLost", e);
+            }
+        }
+
+        public void onQuit() {
+            log("onQuit()");
+            try {
+                mCallback.onQuit();
+            } catch (RemoteException e) {
+                log("Failed to call onQuit", e);
+            }
+        }
+
+        public void installPacketFilter(byte[] filter) {
+            log("installPacketFilter(byte[" + filter.length + "])");
+            try {
+                mCallback.installPacketFilter(filter);
+            } catch (RemoteException e) {
+                log("Failed to call installPacketFilter", e);
+            }
+        }
+
+        public void startReadPacketFilter() {
+            log("startReadPacketFilter()");
+            try {
+                mCallback.startReadPacketFilter();
+            } catch (RemoteException e) {
+                log("Failed to call startReadPacketFilter", e);
+            }
+        }
+
+        public void setFallbackMulticastFilter(boolean enabled) {
+            log("setFallbackMulticastFilter(" + enabled + ")");
+            try {
+                mCallback.setFallbackMulticastFilter(enabled);
+            } catch (RemoteException e) {
+                log("Failed to call setFallbackMulticastFilter", e);
+            }
+        }
+
+        public void setNeighborDiscoveryOffload(boolean enable) {
+            log("setNeighborDiscoveryOffload(" + enable + ")");
+            try {
+                mCallback.setNeighborDiscoveryOffload(enable);
+            } catch (RemoteException e) {
+                log("Failed to call setNeighborDiscoveryOffload", e);
+            }
+        }
+    }
+
+    public static final String DUMP_ARG_CONFIRM = "confirm";
+
+    private static final int CMD_TERMINATE_AFTER_STOP             = 1;
+    private static final int CMD_STOP                             = 2;
+    private static final int CMD_START                            = 3;
+    private static final int CMD_CONFIRM                          = 4;
+    private static final int EVENT_PRE_DHCP_ACTION_COMPLETE       = 5;
+    // Triggered by NetlinkTracker to communicate netlink events.
+    private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 6;
+    private static final int CMD_UPDATE_TCP_BUFFER_SIZES          = 7;
+    private static final int CMD_UPDATE_HTTP_PROXY                = 8;
+    private static final int CMD_SET_MULTICAST_FILTER             = 9;
+    private static final int EVENT_PROVISIONING_TIMEOUT           = 10;
+    private static final int EVENT_DHCPACTION_TIMEOUT             = 11;
+    private static final int EVENT_READ_PACKET_FILTER_COMPLETE    = 12;
+
+    // Internal commands to use instead of trying to call transitionTo() inside
+    // a given State's enter() method. Calling transitionTo() from enter/exit
+    // encounters a Log.wtf() that can cause trouble on eng builds.
+    private static final int CMD_JUMP_STARTED_TO_RUNNING          = 100;
+    private static final int CMD_JUMP_RUNNING_TO_STOPPING         = 101;
+    private static final int CMD_JUMP_STOPPING_TO_STOPPED         = 102;
+
+    // IpClient shares a handler with DhcpClient: commands must not overlap
+    public static final int DHCPCLIENT_CMD_BASE = 1000;
+
+    private static final int MAX_LOG_RECORDS = 500;
+    private static final int MAX_PACKET_RECORDS = 100;
+
+    private static final boolean NO_CALLBACKS = false;
+    private static final boolean SEND_CALLBACKS = true;
+
+    // This must match the interface prefix in clatd.c.
+    // TODO: Revert this hack once IpClient and Nat464Xlat work in concert.
+    private static final String CLAT_PREFIX = "v4-";
+
+    private static final int IMMEDIATE_FAILURE_DURATION = 0;
+
+    private static final int PROV_CHANGE_STILL_NOT_PROVISIONED = 1;
+    private static final int PROV_CHANGE_LOST_PROVISIONING = 2;
+    private static final int PROV_CHANGE_GAINED_PROVISIONING = 3;
+    private static final int PROV_CHANGE_STILL_PROVISIONED = 4;
+
+    private final State mStoppedState = new StoppedState();
+    private final State mStoppingState = new StoppingState();
+    private final State mStartedState = new StartedState();
+    private final State mRunningState = new RunningState();
+
+    private final String mTag;
+    private final Context mContext;
+    private final String mInterfaceName;
+    private final String mClatInterfaceName;
+    @VisibleForTesting
+    protected final IpClientCallbacksWrapper mCallback;
+    private final Dependencies mDependencies;
+    private final CountDownLatch mShutdownLatch;
+    private final ConnectivityManager mCm;
+    private final INetworkManagementService mNwService;
+    private final NetlinkTracker mNetlinkTracker;
+    private final WakeupMessage mProvisioningTimeoutAlarm;
+    private final WakeupMessage mDhcpActionTimeoutAlarm;
+    private final SharedLog mLog;
+    private final LocalLog mConnectivityPacketLog;
+    private final MessageHandlingLogger mMsgStateLogger;
+    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
+    private final InterfaceController mInterfaceCtrl;
+
+    private InterfaceParams mInterfaceParams;
+
+    /**
+     * Non-final member variables accessed only from within our StateMachine.
+     */
+    private LinkProperties mLinkProperties;
+    private android.net.shared.ProvisioningConfiguration mConfiguration;
+    private IpReachabilityMonitor mIpReachabilityMonitor;
+    private DhcpClient mDhcpClient;
+    private DhcpResults mDhcpResults;
+    private String mTcpBufferSizes;
+    private ProxyInfo mHttpProxy;
+    private ApfFilter mApfFilter;
+    private boolean mMulticastFiltering;
+    private long mStartTimeMillis;
+
+    /**
+     * Reading the snapshot is an asynchronous operation initiated by invoking
+     * Callback.startReadPacketFilter() and completed when the WiFi Service responds with an
+     * EVENT_READ_PACKET_FILTER_COMPLETE message. The mApfDataSnapshotComplete condition variable
+     * signals when a new snapshot is ready.
+     */
+    private final ConditionVariable mApfDataSnapshotComplete = new ConditionVariable();
+
+    public static class Dependencies {
+        public INetworkManagementService getNMS() {
+            return INetworkManagementService.Stub.asInterface(
+                    ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
+        }
+
+        public INetd getNetd() {
+            return NetdService.getInstance();
+        }
+
+        /**
+         * Get interface parameters for the specified interface.
+         */
+        public InterfaceParams getInterfaceParams(String ifname) {
+            return InterfaceParams.getByName(ifname);
+        }
+    }
+
+    public IpClient(Context context, String ifName, IIpClientCallbacks callback) {
+        this(context, ifName, callback, new Dependencies());
+    }
+
+    /**
+     * An expanded constructor, useful for dependency injection.
+     * TODO: migrate all test users to mock IpClient directly and remove this ctor.
+     */
+    public IpClient(Context context, String ifName, IIpClientCallbacks callback,
+            INetworkManagementService nwService) {
+        this(context, ifName, callback, new Dependencies() {
+            @Override
+            public INetworkManagementService getNMS() {
+                return nwService;
+            }
+        });
+    }
+
+    @VisibleForTesting
+    IpClient(Context context, String ifName, IIpClientCallbacks callback, Dependencies deps) {
+        super(IpClient.class.getSimpleName() + "." + ifName);
+        Preconditions.checkNotNull(ifName);
+        Preconditions.checkNotNull(callback);
+
+        mTag = getName();
+
+        mContext = context;
+        mInterfaceName = ifName;
+        mClatInterfaceName = CLAT_PREFIX + ifName;
+        mDependencies = deps;
+        mShutdownLatch = new CountDownLatch(1);
+        mCm = mContext.getSystemService(ConnectivityManager.class);
+        mNwService = deps.getNMS();
+
+        sSmLogs.putIfAbsent(mInterfaceName, new SharedLog(MAX_LOG_RECORDS, mTag));
+        mLog = sSmLogs.get(mInterfaceName);
+        sPktLogs.putIfAbsent(mInterfaceName, new LocalLog(MAX_PACKET_RECORDS));
+        mConnectivityPacketLog = sPktLogs.get(mInterfaceName);
+        mMsgStateLogger = new MessageHandlingLogger();
+        mCallback = new IpClientCallbacksWrapper(callback, mLog);
+
+        // TODO: Consider creating, constructing, and passing in some kind of
+        // InterfaceController.Dependencies class.
+        mInterfaceCtrl = new InterfaceController(mInterfaceName, deps.getNetd(), mLog);
+
+        mNetlinkTracker = new NetlinkTracker(
+                mInterfaceName,
+                new NetlinkTracker.Callback() {
+                    @Override
+                    public void update() {
+                        sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED);
+                    }
+                }) {
+            @Override
+            public void interfaceAdded(String iface) {
+                super.interfaceAdded(iface);
+                if (mClatInterfaceName.equals(iface)) {
+                    mCallback.setNeighborDiscoveryOffload(false);
+                } else if (!mInterfaceName.equals(iface)) {
+                    return;
+                }
+
+                final String msg = "interfaceAdded(" + iface + ")";
+                logMsg(msg);
+            }
+
+            @Override
+            public void interfaceRemoved(String iface) {
+                super.interfaceRemoved(iface);
+                // TODO: Also observe mInterfaceName going down and take some
+                // kind of appropriate action.
+                if (mClatInterfaceName.equals(iface)) {
+                    // TODO: consider sending a message to the IpClient main
+                    // StateMachine thread, in case "NDO enabled" state becomes
+                    // tied to more things that 464xlat operation.
+                    mCallback.setNeighborDiscoveryOffload(true);
+                } else if (!mInterfaceName.equals(iface)) {
+                    return;
+                }
+
+                final String msg = "interfaceRemoved(" + iface + ")";
+                logMsg(msg);
+            }
+
+            private void logMsg(String msg) {
+                Log.d(mTag, msg);
+                getHandler().post(() -> mLog.log("OBSERVED " + msg));
+            }
+        };
+
+        mLinkProperties = new LinkProperties();
+        mLinkProperties.setInterfaceName(mInterfaceName);
+
+        mProvisioningTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
+                mTag + ".EVENT_PROVISIONING_TIMEOUT", EVENT_PROVISIONING_TIMEOUT);
+        mDhcpActionTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
+                mTag + ".EVENT_DHCPACTION_TIMEOUT", EVENT_DHCPACTION_TIMEOUT);
+
+        // Anything the StateMachine may access must have been instantiated
+        // before this point.
+        configureAndStartStateMachine();
+
+        // Anything that may send messages to the StateMachine must only be
+        // configured to do so after the StateMachine has started (above).
+        startStateMachineUpdaters();
+    }
+
+    /**
+     * Make a IIpClient connector to communicate with this IpClient.
+     */
+    public IIpClient makeConnector() {
+        return new IpClientConnector();
+    }
+
+    class IpClientConnector extends IIpClient.Stub {
+        @Override
+        public void completedPreDhcpAction() {
+            checkNetworkStackCallingPermission();
+            IpClient.this.completedPreDhcpAction();
+        }
+        @Override
+        public void confirmConfiguration() {
+            checkNetworkStackCallingPermission();
+            IpClient.this.confirmConfiguration();
+        }
+        @Override
+        public void readPacketFilterComplete(byte[] data) {
+            checkNetworkStackCallingPermission();
+            IpClient.this.readPacketFilterComplete(data);
+        }
+        @Override
+        public void shutdown() {
+            checkNetworkStackCallingPermission();
+            IpClient.this.shutdown();
+        }
+        @Override
+        public void startProvisioning(ProvisioningConfigurationParcelable req) {
+            checkNetworkStackCallingPermission();
+            IpClient.this.startProvisioning(ProvisioningConfiguration.fromStableParcelable(req));
+        }
+        @Override
+        public void stop() {
+            checkNetworkStackCallingPermission();
+            IpClient.this.stop();
+        }
+        @Override
+        public void setTcpBufferSizes(String tcpBufferSizes) {
+            checkNetworkStackCallingPermission();
+            IpClient.this.setTcpBufferSizes(tcpBufferSizes);
+        }
+        @Override
+        public void setHttpProxy(ProxyInfoParcelable proxyInfo) {
+            checkNetworkStackCallingPermission();
+            IpClient.this.setHttpProxy(fromStableParcelable(proxyInfo));
+        }
+        @Override
+        public void setMulticastFilter(boolean enabled) {
+            checkNetworkStackCallingPermission();
+            IpClient.this.setMulticastFilter(enabled);
+        }
+    }
+
+    public String getInterfaceName() {
+        return mInterfaceName;
+    }
+
+    private void configureAndStartStateMachine() {
+        // CHECKSTYLE:OFF IndentationCheck
+        addState(mStoppedState);
+        addState(mStartedState);
+            addState(mRunningState, mStartedState);
+        addState(mStoppingState);
+        // CHECKSTYLE:ON IndentationCheck
+
+        setInitialState(mStoppedState);
+
+        super.start();
+    }
+
+    private void startStateMachineUpdaters() {
+        try {
+            mNwService.registerObserver(mNetlinkTracker);
+        } catch (RemoteException e) {
+            logError("Couldn't register NetlinkTracker: %s", e);
+        }
+    }
+
+    private void stopStateMachineUpdaters() {
+        try {
+            mNwService.unregisterObserver(mNetlinkTracker);
+        } catch (RemoteException e) {
+            logError("Couldn't unregister NetlinkTracker: %s", e);
+        }
+    }
+
+    @Override
+    protected void onQuitting() {
+        mCallback.onQuit();
+        mShutdownLatch.countDown();
+    }
+
+    /**
+     * Shut down this IpClient instance altogether.
+     */
+    public void shutdown() {
+        stop();
+        sendMessage(CMD_TERMINATE_AFTER_STOP);
+    }
+
+    /**
+     * Start provisioning with the provided parameters.
+     */
+    public void startProvisioning(ProvisioningConfiguration req) {
+        if (!req.isValid()) {
+            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
+            return;
+        }
+
+        mInterfaceParams = mDependencies.getInterfaceParams(mInterfaceName);
+        if (mInterfaceParams == null) {
+            logError("Failed to find InterfaceParams for " + mInterfaceName);
+            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND);
+            return;
+        }
+
+        mCallback.setNeighborDiscoveryOffload(true);
+        sendMessage(CMD_START, new android.net.shared.ProvisioningConfiguration(req));
+    }
+
+    /**
+     * Stop this IpClient.
+     *
+     * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}.
+     */
+    public void stop() {
+        sendMessage(CMD_STOP);
+    }
+
+    /**
+     * Confirm the provisioning configuration.
+     */
+    public void confirmConfiguration() {
+        sendMessage(CMD_CONFIRM);
+    }
+
+    /**
+     * For clients using {@link ProvisioningConfiguration.Builder#withPreDhcpAction()}, must be
+     * called after {@link IIpClientCallbacks#onPreDhcpAction} to indicate that DHCP is clear to
+     * proceed.
+     */
+    public void completedPreDhcpAction() {
+        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
+    }
+
+    /**
+     * Indicate that packet filter read is complete.
+     */
+    public void readPacketFilterComplete(byte[] data) {
+        sendMessage(EVENT_READ_PACKET_FILTER_COMPLETE, data);
+    }
+
+    /**
+     * Set the TCP buffer sizes to use.
+     *
+     * This may be called, repeatedly, at any time before or after a call to
+     * #startProvisioning(). The setting is cleared upon calling #stop().
+     */
+    public void setTcpBufferSizes(String tcpBufferSizes) {
+        sendMessage(CMD_UPDATE_TCP_BUFFER_SIZES, tcpBufferSizes);
+    }
+
+    /**
+     * Set the HTTP Proxy configuration to use.
+     *
+     * This may be called, repeatedly, at any time before or after a call to
+     * #startProvisioning(). The setting is cleared upon calling #stop().
+     */
+    public void setHttpProxy(ProxyInfo proxyInfo) {
+        sendMessage(CMD_UPDATE_HTTP_PROXY, proxyInfo);
+    }
+
+    /**
+     * Enable or disable the multicast filter.  Attempts to use APF to accomplish the filtering,
+     * if not, Callback.setFallbackMulticastFilter() is called.
+     */
+    public void setMulticastFilter(boolean enabled) {
+        sendMessage(CMD_SET_MULTICAST_FILTER, enabled);
+    }
+
+    /**
+     * Dump logs of this IpClient.
+     */
+    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        if (args != null && args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) {
+            // Execute confirmConfiguration() and take no further action.
+            confirmConfiguration();
+            return;
+        }
+
+        // Thread-unsafe access to mApfFilter but just used for debugging.
+        final ApfFilter apfFilter = mApfFilter;
+        final android.net.shared.ProvisioningConfiguration provisioningConfig = mConfiguration;
+        final ApfCapabilities apfCapabilities = (provisioningConfig != null)
+                ? provisioningConfig.mApfCapabilities : null;
+
+        IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
+        pw.println(mTag + " APF dump:");
+        pw.increaseIndent();
+        if (apfFilter != null) {
+            if (apfCapabilities.hasDataAccess()) {
+                // Request a new snapshot, then wait for it.
+                mApfDataSnapshotComplete.close();
+                mCallback.startReadPacketFilter();
+                if (!mApfDataSnapshotComplete.block(1000)) {
+                    pw.print("TIMEOUT: DUMPING STALE APF SNAPSHOT");
+                }
+            }
+            apfFilter.dump(pw);
+
+        } else {
+            pw.print("No active ApfFilter; ");
+            if (provisioningConfig == null) {
+                pw.println("IpClient not yet started.");
+            } else if (apfCapabilities == null || apfCapabilities.apfVersionSupported == 0) {
+                pw.println("Hardware does not support APF.");
+            } else {
+                pw.println("ApfFilter not yet started, APF capabilities: " + apfCapabilities);
+            }
+        }
+        pw.decreaseIndent();
+        pw.println();
+        pw.println(mTag + " current ProvisioningConfiguration:");
+        pw.increaseIndent();
+        pw.println(Objects.toString(provisioningConfig, "N/A"));
+        pw.decreaseIndent();
+
+        final IpReachabilityMonitor iprm = mIpReachabilityMonitor;
+        if (iprm != null) {
+            pw.println();
+            pw.println(mTag + " current IpReachabilityMonitor state:");
+            pw.increaseIndent();
+            iprm.dump(pw);
+            pw.decreaseIndent();
+        }
+
+        pw.println();
+        pw.println(mTag + " StateMachine dump:");
+        pw.increaseIndent();
+        mLog.dump(fd, pw, args);
+        pw.decreaseIndent();
+
+        pw.println();
+        pw.println(mTag + " connectivity packet log:");
+        pw.println();
+        pw.println("Debug with python and scapy via:");
+        pw.println("shell$ python");
+        pw.println(">>> from scapy import all as scapy");
+        pw.println(">>> scapy.Ether(\"<paste_hex_string>\".decode(\"hex\")).show2()");
+        pw.println();
+
+        pw.increaseIndent();
+        mConnectivityPacketLog.readOnlyLocalLog().dump(fd, pw, args);
+        pw.decreaseIndent();
+    }
+
+
+    /**
+     * Internals.
+     */
+
+    @Override
+    protected String getWhatToString(int what) {
+        return sWhatToString.get(what, "UNKNOWN: " + Integer.toString(what));
+    }
+
+    @Override
+    protected String getLogRecString(Message msg) {
+        final String logLine = String.format(
+                "%s/%d %d %d %s [%s]",
+                mInterfaceName, (mInterfaceParams == null) ? -1 : mInterfaceParams.index,
+                msg.arg1, msg.arg2, Objects.toString(msg.obj), mMsgStateLogger);
+
+        final String richerLogLine = getWhatToString(msg.what) + " " + logLine;
+        mLog.log(richerLogLine);
+        if (DBG) {
+            Log.d(mTag, richerLogLine);
+        }
+
+        mMsgStateLogger.reset();
+        return logLine;
+    }
+
+    @Override
+    protected boolean recordLogRec(Message msg) {
+        // Don't log EVENT_NETLINK_LINKPROPERTIES_CHANGED. They can be noisy,
+        // and we already log any LinkProperties change that results in an
+        // invocation of IpClient.Callback#onLinkPropertiesChange().
+        final boolean shouldLog = (msg.what != EVENT_NETLINK_LINKPROPERTIES_CHANGED);
+        if (!shouldLog) {
+            mMsgStateLogger.reset();
+        }
+        return shouldLog;
+    }
+
+    private void logError(String fmt, Object... args) {
+        final String msg = "ERROR " + String.format(fmt, args);
+        Log.e(mTag, msg);
+        mLog.log(msg);
+    }
+
+    // This needs to be called with care to ensure that our LinkProperties
+    // are in sync with the actual LinkProperties of the interface. For example,
+    // we should only call this if we know for sure that there are no IP addresses
+    // assigned to the interface, etc.
+    private void resetLinkProperties() {
+        mNetlinkTracker.clearLinkProperties();
+        mConfiguration = null;
+        mDhcpResults = null;
+        mTcpBufferSizes = "";
+        mHttpProxy = null;
+
+        mLinkProperties = new LinkProperties();
+        mLinkProperties.setInterfaceName(mInterfaceName);
+    }
+
+    private void recordMetric(final int type) {
+        // We may record error metrics prior to starting.
+        // Map this to IMMEDIATE_FAILURE_DURATION.
+        final long duration = (mStartTimeMillis > 0)
+                ? (SystemClock.elapsedRealtime() - mStartTimeMillis)
+                : IMMEDIATE_FAILURE_DURATION;
+        mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration));
+    }
+
+    // For now: use WifiStateMachine's historical notion of provisioned.
+    @VisibleForTesting
+    static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) {
+        // For historical reasons, we should connect even if all we have is
+        // an IPv4 address and nothing else.
+        if (lp.hasIPv4Address() || lp.isProvisioned()) {
+            return true;
+        }
+        if (config == null) {
+            return false;
+        }
+
+        // When an InitialConfiguration is specified, ignore any difference with previous
+        // properties and instead check if properties observed match the desired properties.
+        return config.isProvisionedBy(lp.getLinkAddresses(), lp.getRoutes());
+    }
+
+    // TODO: Investigate folding all this into the existing static function
+    // LinkProperties.compareProvisioning() or some other single function that
+    // takes two LinkProperties objects and returns a ProvisioningChange
+    // object that is a correct and complete assessment of what changed, taking
+    // account of the asymmetries described in the comments in this function.
+    // Then switch to using it everywhere (IpReachabilityMonitor, etc.).
+    private int compareProvisioning(LinkProperties oldLp, LinkProperties newLp) {
+        int delta;
+        InitialConfiguration config = mConfiguration != null ? mConfiguration.mInitialConfig : null;
+        final boolean wasProvisioned = isProvisioned(oldLp, config);
+        final boolean isProvisioned = isProvisioned(newLp, config);
+
+        if (!wasProvisioned && isProvisioned) {
+            delta = PROV_CHANGE_GAINED_PROVISIONING;
+        } else if (wasProvisioned && isProvisioned) {
+            delta = PROV_CHANGE_STILL_PROVISIONED;
+        } else if (!wasProvisioned && !isProvisioned) {
+            delta = PROV_CHANGE_STILL_NOT_PROVISIONED;
+        } else {
+            // (wasProvisioned && !isProvisioned)
+            //
+            // Note that this is true even if we lose a configuration element
+            // (e.g., a default gateway) that would not be required to advance
+            // into provisioned state. This is intended: if we have a default
+            // router and we lose it, that's a sure sign of a problem, but if
+            // we connect to a network with no IPv4 DNS servers, we consider
+            // that to be a network without DNS servers and connect anyway.
+            //
+            // See the comment below.
+            delta = PROV_CHANGE_LOST_PROVISIONING;
+        }
+
+        final boolean lostIPv6 = oldLp.isIPv6Provisioned() && !newLp.isIPv6Provisioned();
+        final boolean lostIPv4Address = oldLp.hasIPv4Address() && !newLp.hasIPv4Address();
+        final boolean lostIPv6Router = oldLp.hasIPv6DefaultRoute() && !newLp.hasIPv6DefaultRoute();
+
+        // If bad wifi avoidance is disabled, then ignore IPv6 loss of
+        // provisioning. Otherwise, when a hotspot that loses Internet
+        // access sends out a 0-lifetime RA to its clients, the clients
+        // will disconnect and then reconnect, avoiding the bad hotspot,
+        // instead of getting stuck on the bad hotspot. http://b/31827713 .
+        //
+        // This is incorrect because if the hotspot then regains Internet
+        // access with a different prefix, TCP connections on the
+        // deprecated addresses will remain stuck.
+        //
+        // Note that we can still be disconnected by IpReachabilityMonitor
+        // if the IPv6 default gateway (but not the IPv6 DNS servers; see
+        // accompanying code in IpReachabilityMonitor) is unreachable.
+        final boolean ignoreIPv6ProvisioningLoss =
+                mConfiguration != null && mConfiguration.mUsingMultinetworkPolicyTracker
+                && mCm.getAvoidBadWifi();
+
+        // Additionally:
+        //
+        // Partial configurations (e.g., only an IPv4 address with no DNS
+        // servers and no default route) are accepted as long as DHCPv4
+        // succeeds. On such a network, isProvisioned() will always return
+        // false, because the configuration is not complete, but we want to
+        // connect anyway. It might be a disconnected network such as a
+        // Chromecast or a wireless printer, for example.
+        //
+        // Because on such a network isProvisioned() will always return false,
+        // delta will never be LOST_PROVISIONING. So check for loss of
+        // provisioning here too.
+        if (lostIPv4Address || (lostIPv6 && !ignoreIPv6ProvisioningLoss)) {
+            delta = PROV_CHANGE_LOST_PROVISIONING;
+        }
+
+        // Additionally:
+        //
+        // If the previous link properties had a global IPv6 address and an
+        // IPv6 default route then also consider the loss of that default route
+        // to be a loss of provisioning. See b/27962810.
+        if (oldLp.hasGlobalIPv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
+            delta = PROV_CHANGE_LOST_PROVISIONING;
+        }
+
+        return delta;
+    }
+
+    private void dispatchCallback(int delta, LinkProperties newLp) {
+        switch (delta) {
+            case PROV_CHANGE_GAINED_PROVISIONING:
+                if (DBG) {
+                    Log.d(mTag, "onProvisioningSuccess()");
+                }
+                recordMetric(IpManagerEvent.PROVISIONING_OK);
+                mCallback.onProvisioningSuccess(newLp);
+                break;
+
+            case PROV_CHANGE_LOST_PROVISIONING:
+                if (DBG) {
+                    Log.d(mTag, "onProvisioningFailure()");
+                }
+                recordMetric(IpManagerEvent.PROVISIONING_FAIL);
+                mCallback.onProvisioningFailure(newLp);
+                break;
+
+            default:
+                if (DBG) {
+                    Log.d(mTag, "onLinkPropertiesChange()");
+                }
+                mCallback.onLinkPropertiesChange(newLp);
+                break;
+        }
+    }
+
+    // Updates all IpClient-related state concerned with LinkProperties.
+    // Returns a ProvisioningChange for possibly notifying other interested
+    // parties that are not fronted by IpClient.
+    private int setLinkProperties(LinkProperties newLp) {
+        if (mApfFilter != null) {
+            mApfFilter.setLinkProperties(newLp);
+        }
+        if (mIpReachabilityMonitor != null) {
+            mIpReachabilityMonitor.updateLinkProperties(newLp);
+        }
+
+        int delta = compareProvisioning(mLinkProperties, newLp);
+        mLinkProperties = new LinkProperties(newLp);
+
+        if (delta == PROV_CHANGE_GAINED_PROVISIONING) {
+            // TODO: Add a proper ProvisionedState and cancel the alarm in
+            // its enter() method.
+            mProvisioningTimeoutAlarm.cancel();
+        }
+
+        return delta;
+    }
+
+    private LinkProperties assembleLinkProperties() {
+        // [1] Create a new LinkProperties object to populate.
+        LinkProperties newLp = new LinkProperties();
+        newLp.setInterfaceName(mInterfaceName);
+
+        // [2] Pull in data from netlink:
+        //         - IPv4 addresses
+        //         - IPv6 addresses
+        //         - IPv6 routes
+        //         - IPv6 DNS servers
+        //
+        // N.B.: this is fundamentally race-prone and should be fixed by
+        // changing NetlinkTracker from a hybrid edge/level model to an
+        // edge-only model, or by giving IpClient its own netlink socket(s)
+        // so as to track all required information directly.
+        LinkProperties netlinkLinkProperties = mNetlinkTracker.getLinkProperties();
+        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
+        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
+            newLp.addRoute(route);
+        }
+        addAllReachableDnsServers(newLp, netlinkLinkProperties.getDnsServers());
+
+        // [3] Add in data from DHCPv4, if available.
+        //
+        // mDhcpResults is never shared with any other owner so we don't have
+        // to worry about concurrent modification.
+        if (mDhcpResults != null) {
+            for (RouteInfo route : mDhcpResults.getRoutes(mInterfaceName)) {
+                newLp.addRoute(route);
+            }
+            addAllReachableDnsServers(newLp, mDhcpResults.dnsServers);
+            newLp.setDomains(mDhcpResults.domains);
+
+            if (mDhcpResults.mtu != 0) {
+                newLp.setMtu(mDhcpResults.mtu);
+            }
+        }
+
+        // [4] Add in TCP buffer sizes and HTTP Proxy config, if available.
+        if (!TextUtils.isEmpty(mTcpBufferSizes)) {
+            newLp.setTcpBufferSizes(mTcpBufferSizes);
+        }
+        if (mHttpProxy != null) {
+            newLp.setHttpProxy(mHttpProxy);
+        }
+
+        // [5] Add data from InitialConfiguration
+        if (mConfiguration != null && mConfiguration.mInitialConfig != null) {
+            InitialConfiguration config = mConfiguration.mInitialConfig;
+            // Add InitialConfiguration routes and dns server addresses once all addresses
+            // specified in the InitialConfiguration have been observed with Netlink.
+            if (config.isProvisionedBy(newLp.getLinkAddresses(), null)) {
+                for (IpPrefix prefix : config.directlyConnectedRoutes) {
+                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName));
+                }
+            }
+            addAllReachableDnsServers(newLp, config.dnsServers);
+        }
+        final LinkProperties oldLp = mLinkProperties;
+        if (DBG) {
+            Log.d(mTag, String.format("Netlink-seen LPs: %s, new LPs: %s; old LPs: %s",
+                    netlinkLinkProperties, newLp, oldLp));
+        }
+
+        // TODO: also learn via netlink routes specified by an InitialConfiguration and specified
+        // from a static IP v4 config instead of manually patching them in in steps [3] and [5].
+        return newLp;
+    }
+
+    private static void addAllReachableDnsServers(
+            LinkProperties lp, Iterable<InetAddress> dnses) {
+        // TODO: Investigate deleting this reachability check.  We should be
+        // able to pass everything down to netd and let netd do evaluation
+        // and RFC6724-style sorting.
+        for (InetAddress dns : dnses) {
+            if (!dns.isAnyLocalAddress() && lp.isReachable(dns)) {
+                lp.addDnsServer(dns);
+            }
+        }
+    }
+
+    // Returns false if we have lost provisioning, true otherwise.
+    private boolean handleLinkPropertiesUpdate(boolean sendCallbacks) {
+        final LinkProperties newLp = assembleLinkProperties();
+        if (Objects.equals(newLp, mLinkProperties)) {
+            return true;
+        }
+        final int delta = setLinkProperties(newLp);
+        if (sendCallbacks) {
+            dispatchCallback(delta, newLp);
+        }
+        return (delta != PROV_CHANGE_LOST_PROVISIONING);
+    }
+
+    private void handleIPv4Success(DhcpResults dhcpResults) {
+        mDhcpResults = new DhcpResults(dhcpResults);
+        final LinkProperties newLp = assembleLinkProperties();
+        final int delta = setLinkProperties(newLp);
+
+        if (DBG) {
+            Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
+        }
+        mCallback.onNewDhcpResults(dhcpResults);
+        dispatchCallback(delta, newLp);
+    }
+
+    private void handleIPv4Failure() {
+        // TODO: Investigate deleting this clearIPv4Address() call.
+        //
+        // DhcpClient will send us CMD_CLEAR_LINKADDRESS in all circumstances
+        // that could trigger a call to this function. If we missed handling
+        // that message in StartedState for some reason we would still clear
+        // any addresses upon entry to StoppedState.
+        mInterfaceCtrl.clearIPv4Address();
+        mDhcpResults = null;
+        if (DBG) {
+            Log.d(mTag, "onNewDhcpResults(null)");
+        }
+        mCallback.onNewDhcpResults(null);
+
+        handleProvisioningFailure();
+    }
+
+    private void handleProvisioningFailure() {
+        final LinkProperties newLp = assembleLinkProperties();
+        int delta = setLinkProperties(newLp);
+        // If we've gotten here and we're still not provisioned treat that as
+        // a total loss of provisioning.
+        //
+        // Either (a) static IP configuration failed or (b) DHCPv4 failed AND
+        // there was no usable IPv6 obtained before a non-zero provisioning
+        // timeout expired.
+        //
+        // Regardless: GAME OVER.
+        if (delta == PROV_CHANGE_STILL_NOT_PROVISIONED) {
+            delta = PROV_CHANGE_LOST_PROVISIONING;
+        }
+
+        dispatchCallback(delta, newLp);
+        if (delta == PROV_CHANGE_LOST_PROVISIONING) {
+            transitionTo(mStoppingState);
+        }
+    }
+
+    private void doImmediateProvisioningFailure(int failureType) {
+        logError("onProvisioningFailure(): %s", failureType);
+        recordMetric(failureType);
+        mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties));
+    }
+
+    private boolean startIPv4() {
+        // If we have a StaticIpConfiguration attempt to apply it and
+        // handle the result accordingly.
+        if (mConfiguration.mStaticIpConfig != null) {
+            if (mInterfaceCtrl.setIPv4Address(mConfiguration.mStaticIpConfig.ipAddress)) {
+                handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
+            } else {
+                return false;
+            }
+        } else {
+            // Start DHCPv4.
+            mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams);
+            mDhcpClient.registerForPreDhcpNotification();
+            mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
+        }
+
+        return true;
+    }
+
+    private boolean startIPv6() {
+        return mInterfaceCtrl.setIPv6PrivacyExtensions(true)
+                && mInterfaceCtrl.setIPv6AddrGenModeIfSupported(mConfiguration.mIPv6AddrGenMode)
+                && mInterfaceCtrl.enableIPv6();
+    }
+
+    private boolean applyInitialConfig(InitialConfiguration config) {
+        // TODO: also support specifying a static IPv4 configuration in InitialConfiguration.
+        for (LinkAddress addr : findAll(config.ipAddresses, LinkAddress::isIPv6)) {
+            if (!mInterfaceCtrl.addAddress(addr)) return false;
+        }
+
+        return true;
+    }
+
+    private boolean startIpReachabilityMonitor() {
+        try {
+            // TODO: Fetch these parameters from settings, and install a
+            // settings observer to watch for update and re-program these
+            // parameters (Q: is this level of dynamic updatability really
+            // necessary or does reading from settings at startup suffice?).
+            final int numSolicits = 5;
+            final int interSolicitIntervalMs = 750;
+            setNeighborParameters(mDependencies.getNetd(), mInterfaceName,
+                    numSolicits, interSolicitIntervalMs);
+        } catch (Exception e) {
+            mLog.e("Failed to adjust neighbor parameters", e);
+            // Carry on using the system defaults (currently: 3, 1000);
+        }
+
+        try {
+            mIpReachabilityMonitor = new IpReachabilityMonitor(
+                    mContext,
+                    mInterfaceParams,
+                    getHandler(),
+                    mLog,
+                    new IpReachabilityMonitor.Callback() {
+                        @Override
+                        public void notifyLost(InetAddress ip, String logMsg) {
+                            mCallback.onReachabilityLost(logMsg);
+                        }
+                    },
+                    mConfiguration.mUsingMultinetworkPolicyTracker);
+        } catch (IllegalArgumentException iae) {
+            // Failed to start IpReachabilityMonitor. Log it and call
+            // onProvisioningFailure() immediately.
+            //
+            // See http://b/31038971.
+            logError("IpReachabilityMonitor failure: %s", iae);
+            mIpReachabilityMonitor = null;
+        }
+
+        return (mIpReachabilityMonitor != null);
+    }
+
+    private void stopAllIP() {
+        // We don't need to worry about routes, just addresses, because:
+        //     - disableIpv6() will clear autoconf IPv6 routes as well, and
+        //     - we don't get IPv4 routes from netlink
+        // so we neither react to nor need to wait for changes in either.
+
+        mInterfaceCtrl.disableIPv6();
+        mInterfaceCtrl.clearAllAddresses();
+    }
+
+    class StoppedState extends State {
+        @Override
+        public void enter() {
+            stopAllIP();
+
+            resetLinkProperties();
+            if (mStartTimeMillis > 0) {
+                // Completed a life-cycle; send a final empty LinkProperties
+                // (cleared in resetLinkProperties() above) and record an event.
+                mCallback.onLinkPropertiesChange(new LinkProperties(mLinkProperties));
+                recordMetric(IpManagerEvent.COMPLETE_LIFECYCLE);
+                mStartTimeMillis = 0;
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_TERMINATE_AFTER_STOP:
+                    stopStateMachineUpdaters();
+                    quit();
+                    break;
+
+                case CMD_STOP:
+                    break;
+
+                case CMD_START:
+                    mConfiguration = (android.net.shared.ProvisioningConfiguration) msg.obj;
+                    transitionTo(mStartedState);
+                    break;
+
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    break;
+
+                case CMD_UPDATE_TCP_BUFFER_SIZES:
+                    mTcpBufferSizes = (String) msg.obj;
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    break;
+
+                case CMD_UPDATE_HTTP_PROXY:
+                    mHttpProxy = (ProxyInfo) msg.obj;
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    break;
+
+                case CMD_SET_MULTICAST_FILTER:
+                    mMulticastFiltering = (boolean) msg.obj;
+                    break;
+
+                case DhcpClient.CMD_ON_QUIT:
+                    // Everything is already stopped.
+                    logError("Unexpected CMD_ON_QUIT (already stopped).");
+                    break;
+
+                default:
+                    return NOT_HANDLED;
+            }
+
+            mMsgStateLogger.handled(this, getCurrentState());
+            return HANDLED;
+        }
+    }
+
+    class StoppingState extends State {
+        @Override
+        public void enter() {
+            if (mDhcpClient == null) {
+                // There's no DHCPv4 for which to wait; proceed to stopped.
+                deferMessage(obtainMessage(CMD_JUMP_STOPPING_TO_STOPPED));
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_JUMP_STOPPING_TO_STOPPED:
+                    transitionTo(mStoppedState);
+                    break;
+
+                case CMD_STOP:
+                    break;
+
+                case DhcpClient.CMD_CLEAR_LINKADDRESS:
+                    mInterfaceCtrl.clearIPv4Address();
+                    break;
+
+                case DhcpClient.CMD_ON_QUIT:
+                    mDhcpClient = null;
+                    transitionTo(mStoppedState);
+                    break;
+
+                default:
+                    deferMessage(msg);
+            }
+
+            mMsgStateLogger.handled(this, getCurrentState());
+            return HANDLED;
+        }
+    }
+
+    class StartedState extends State {
+        @Override
+        public void enter() {
+            mStartTimeMillis = SystemClock.elapsedRealtime();
+
+            if (mConfiguration.mProvisioningTimeoutMs > 0) {
+                final long alarmTime = SystemClock.elapsedRealtime()
+                        + mConfiguration.mProvisioningTimeoutMs;
+                mProvisioningTimeoutAlarm.schedule(alarmTime);
+            }
+
+            if (readyToProceed()) {
+                deferMessage(obtainMessage(CMD_JUMP_STARTED_TO_RUNNING));
+            } else {
+                // Clear all IPv4 and IPv6 before proceeding to RunningState.
+                // Clean up any leftover state from an abnormal exit from
+                // tethering or during an IpClient restart.
+                stopAllIP();
+            }
+        }
+
+        @Override
+        public void exit() {
+            mProvisioningTimeoutAlarm.cancel();
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_JUMP_STARTED_TO_RUNNING:
+                    transitionTo(mRunningState);
+                    break;
+
+                case CMD_STOP:
+                    transitionTo(mStoppingState);
+                    break;
+
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    handleLinkPropertiesUpdate(NO_CALLBACKS);
+                    if (readyToProceed()) {
+                        transitionTo(mRunningState);
+                    }
+                    break;
+
+                case EVENT_PROVISIONING_TIMEOUT:
+                    handleProvisioningFailure();
+                    break;
+
+                default:
+                    // It's safe to process messages out of order because the
+                    // only message that can both
+                    //     a) be received at this time and
+                    //     b) affect provisioning state
+                    // is EVENT_NETLINK_LINKPROPERTIES_CHANGED (handled above).
+                    deferMessage(msg);
+            }
+
+            mMsgStateLogger.handled(this, getCurrentState());
+            return HANDLED;
+        }
+
+        private boolean readyToProceed() {
+            return (!mLinkProperties.hasIPv4Address() && !mLinkProperties.hasGlobalIPv6Address());
+        }
+    }
+
+    class RunningState extends State {
+        private ConnectivityPacketTracker mPacketTracker;
+        private boolean mDhcpActionInFlight;
+
+        @Override
+        public void enter() {
+            ApfFilter.ApfConfiguration apfConfig = new ApfFilter.ApfConfiguration();
+            apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;
+            apfConfig.multicastFilter = mMulticastFiltering;
+            // Get the Configuration for ApfFilter from Context
+            apfConfig.ieee802_3Filter =
+                    mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames);
+            apfConfig.ethTypeBlackList =
+                    mContext.getResources().getIntArray(R.array.config_apfEthTypeBlackList);
+            mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback);
+            // TODO: investigate the effects of any multicast filtering racing/interfering with the
+            // rest of this IP configuration startup.
+            if (mApfFilter == null) {
+                mCallback.setFallbackMulticastFilter(mMulticastFiltering);
+            }
+
+            mPacketTracker = createPacketTracker();
+            if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);
+
+            if (mConfiguration.mEnableIPv6 && !startIPv6()) {
+                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
+                enqueueJumpToStoppingState();
+                return;
+            }
+
+            if (mConfiguration.mEnableIPv4 && !startIPv4()) {
+                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);
+                enqueueJumpToStoppingState();
+                return;
+            }
+
+            final InitialConfiguration config = mConfiguration.mInitialConfig;
+            if ((config != null) && !applyInitialConfig(config)) {
+                // TODO introduce a new IpManagerEvent constant to distinguish this error case.
+                doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
+                enqueueJumpToStoppingState();
+                return;
+            }
+
+            if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) {
+                doImmediateProvisioningFailure(
+                        IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR);
+                enqueueJumpToStoppingState();
+                return;
+            }
+        }
+
+        @Override
+        public void exit() {
+            stopDhcpAction();
+
+            if (mIpReachabilityMonitor != null) {
+                mIpReachabilityMonitor.stop();
+                mIpReachabilityMonitor = null;
+            }
+
+            if (mDhcpClient != null) {
+                mDhcpClient.sendMessage(DhcpClient.CMD_STOP_DHCP);
+                mDhcpClient.doQuit();
+            }
+
+            if (mPacketTracker != null) {
+                mPacketTracker.stop();
+                mPacketTracker = null;
+            }
+
+            if (mApfFilter != null) {
+                mApfFilter.shutdown();
+                mApfFilter = null;
+            }
+
+            resetLinkProperties();
+        }
+
+        private void enqueueJumpToStoppingState() {
+            deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING));
+        }
+
+        private ConnectivityPacketTracker createPacketTracker() {
+            try {
+                return new ConnectivityPacketTracker(
+                        getHandler(), mInterfaceParams, mConnectivityPacketLog);
+            } catch (IllegalArgumentException e) {
+                return null;
+            }
+        }
+
+        private void ensureDhcpAction() {
+            if (!mDhcpActionInFlight) {
+                mCallback.onPreDhcpAction();
+                mDhcpActionInFlight = true;
+                final long alarmTime = SystemClock.elapsedRealtime()
+                        + mConfiguration.mRequestedPreDhcpActionMs;
+                mDhcpActionTimeoutAlarm.schedule(alarmTime);
+            }
+        }
+
+        private void stopDhcpAction() {
+            mDhcpActionTimeoutAlarm.cancel();
+            if (mDhcpActionInFlight) {
+                mCallback.onPostDhcpAction();
+                mDhcpActionInFlight = false;
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_JUMP_RUNNING_TO_STOPPING:
+                case CMD_STOP:
+                    transitionTo(mStoppingState);
+                    break;
+
+                case CMD_START:
+                    logError("ALERT: START received in StartedState. Please fix caller.");
+                    break;
+
+                case CMD_CONFIRM:
+                    // TODO: Possibly introduce a second type of confirmation
+                    // that both probes (a) on-link neighbors and (b) does
+                    // a DHCPv4 RENEW.  We used to do this on Wi-Fi framework
+                    // roams.
+                    if (mIpReachabilityMonitor != null) {
+                        mIpReachabilityMonitor.probeAll();
+                    }
+                    break;
+
+                case EVENT_PRE_DHCP_ACTION_COMPLETE:
+                    // It's possible to reach here if, for example, someone
+                    // calls completedPreDhcpAction() after provisioning with
+                    // a static IP configuration.
+                    if (mDhcpClient != null) {
+                        mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
+                    }
+                    break;
+
+                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                    if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) {
+                        transitionTo(mStoppingState);
+                    }
+                    break;
+
+                case CMD_UPDATE_TCP_BUFFER_SIZES:
+                    mTcpBufferSizes = (String) msg.obj;
+                    // This cannot possibly change provisioning state.
+                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
+                    break;
+
+                case CMD_UPDATE_HTTP_PROXY:
+                    mHttpProxy = (ProxyInfo) msg.obj;
+                    // This cannot possibly change provisioning state.
+                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
+                    break;
+
+                case CMD_SET_MULTICAST_FILTER: {
+                    mMulticastFiltering = (boolean) msg.obj;
+                    if (mApfFilter != null) {
+                        mApfFilter.setMulticastFilter(mMulticastFiltering);
+                    } else {
+                        mCallback.setFallbackMulticastFilter(mMulticastFiltering);
+                    }
+                    break;
+                }
+
+                case EVENT_READ_PACKET_FILTER_COMPLETE: {
+                    if (mApfFilter != null) {
+                        mApfFilter.setDataSnapshot((byte[]) msg.obj);
+                    }
+                    mApfDataSnapshotComplete.open();
+                    break;
+                }
+
+                case EVENT_DHCPACTION_TIMEOUT:
+                    stopDhcpAction();
+                    break;
+
+                case DhcpClient.CMD_PRE_DHCP_ACTION:
+                    if (mConfiguration.mRequestedPreDhcpActionMs > 0) {
+                        ensureDhcpAction();
+                    } else {
+                        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
+                    }
+                    break;
+
+                case DhcpClient.CMD_CLEAR_LINKADDRESS:
+                    mInterfaceCtrl.clearIPv4Address();
+                    break;
+
+                case DhcpClient.CMD_CONFIGURE_LINKADDRESS: {
+                    final LinkAddress ipAddress = (LinkAddress) msg.obj;
+                    if (mInterfaceCtrl.setIPv4Address(ipAddress)) {
+                        mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED);
+                    } else {
+                        logError("Failed to set IPv4 address.");
+                        dispatchCallback(PROV_CHANGE_LOST_PROVISIONING,
+                                new LinkProperties(mLinkProperties));
+                        transitionTo(mStoppingState);
+                    }
+                    break;
+                }
+
+                // This message is only received when:
+                //
+                //     a) initial address acquisition succeeds,
+                //     b) renew succeeds or is NAK'd,
+                //     c) rebind succeeds or is NAK'd, or
+                //     c) the lease expires,
+                //
+                // but never when initial address acquisition fails. The latter
+                // condition is now governed by the provisioning timeout.
+                case DhcpClient.CMD_POST_DHCP_ACTION:
+                    stopDhcpAction();
+
+                    switch (msg.arg1) {
+                        case DhcpClient.DHCP_SUCCESS:
+                            handleIPv4Success((DhcpResults) msg.obj);
+                            break;
+                        case DhcpClient.DHCP_FAILURE:
+                            handleIPv4Failure();
+                            break;
+                        default:
+                            logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);
+                    }
+                    break;
+
+                case DhcpClient.CMD_ON_QUIT:
+                    // DHCPv4 quit early for some reason.
+                    logError("Unexpected CMD_ON_QUIT.");
+                    mDhcpClient = null;
+                    break;
+
+                default:
+                    return NOT_HANDLED;
+            }
+
+            mMsgStateLogger.handled(this, getCurrentState());
+            return HANDLED;
+        }
+    }
+
+    private static class MessageHandlingLogger {
+        public String processedInState;
+        public String receivedInState;
+
+        public void reset() {
+            processedInState = null;
+            receivedInState = null;
+        }
+
+        public void handled(State processedIn, IState receivedIn) {
+            processedInState = processedIn.getClass().getSimpleName();
+            receivedInState = receivedIn.getName();
+        }
+
+        public String toString() {
+            return String.format("rcvd_in=%s, proc_in=%s",
+                                 receivedInState, processedInState);
+        }
+    }
+
+    private static void setNeighborParameters(
+            INetd netd, String ifName, int numSolicits, int interSolicitIntervalMs)
+            throws RemoteException, IllegalArgumentException {
+        Preconditions.checkNotNull(netd);
+        Preconditions.checkArgument(!TextUtils.isEmpty(ifName));
+        Preconditions.checkArgument(numSolicits > 0);
+        Preconditions.checkArgument(interSolicitIntervalMs > 0);
+
+        for (int family : new Integer[]{INetd.IPV4, INetd.IPV6}) {
+            netd.setProcSysNet(family, INetd.NEIGH, ifName, "retrans_time_ms",
+                    Integer.toString(interSolicitIntervalMs));
+            netd.setProcSysNet(family, INetd.NEIGH, ifName, "ucast_solicit",
+                    Integer.toString(numSolicits));
+        }
+    }
+
+    // TODO: extract out into CollectionUtils.
+    static <T> boolean any(Iterable<T> coll, Predicate<T> fn) {
+        for (T t : coll) {
+            if (fn.test(t)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static <T> boolean all(Iterable<T> coll, Predicate<T> fn) {
+        return !any(coll, not(fn));
+    }
+
+    static <T> Predicate<T> not(Predicate<T> fn) {
+        return (t) -> !fn.test(t);
+    }
+
+    static <T> String join(String delimiter, Collection<T> coll) {
+        return coll.stream().map(Object::toString).collect(Collectors.joining(delimiter));
+    }
+
+    static <T> T find(Iterable<T> coll, Predicate<T> fn) {
+        for (T t: coll) {
+            if (fn.test(t)) {
+                return t;
+            }
+        }
+        return null;
+    }
+
+    static <T> List<T> findAll(Collection<T> coll, Predicate<T> fn) {
+        return coll.stream().filter(fn).collect(Collectors.toList());
+    }
+}
diff --git a/src/android/net/ip/IpNeighborMonitor.java b/src/android/net/ip/IpNeighborMonitor.java
new file mode 100644
index 0000000..eb993a4
--- /dev/null
+++ b/src/android/net/ip/IpNeighborMonitor.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2017 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.ip;
+
+import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH;
+import static android.net.netlink.NetlinkConstants.hexify;
+import static android.net.netlink.NetlinkConstants.stringForNlMsgType;
+import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
+
+import android.net.MacAddress;
+import android.net.netlink.NetlinkErrorMessage;
+import android.net.netlink.NetlinkMessage;
+import android.net.netlink.NetlinkSocket;
+import android.net.netlink.RtNetlinkNeighborMessage;
+import android.net.netlink.StructNdMsg;
+import android.net.util.PacketReader;
+import android.net.util.SharedLog;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Log;
+
+import com.android.internal.util.BitUtils;
+
+import libcore.io.IoUtils;
+
+import java.io.FileDescriptor;
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.StringJoiner;
+
+
+/**
+ * IpNeighborMonitor.
+ *
+ * Monitors the kernel rtnetlink neighbor notifications and presents to callers
+ * NeighborEvents describing each event. Callers can provide a consumer instance
+ * to both filter (e.g. by interface index and IP address) and handle the
+ * generated NeighborEvents.
+ *
+ * @hide
+ */
+public class IpNeighborMonitor extends PacketReader {
+    private static final String TAG = IpNeighborMonitor.class.getSimpleName();
+    private static final boolean DBG = false;
+    private static final boolean VDBG = false;
+
+    /**
+     * Make the kernel perform neighbor reachability detection (IPv4 ARP or IPv6 ND)
+     * for the given IP address on the specified interface index.
+     *
+     * @return 0 if the request was successfully passed to the kernel; otherwise return
+     *         a non-zero error code.
+     */
+    public static int startKernelNeighborProbe(int ifIndex, InetAddress ip) {
+        final String msgSnippet = "probing ip=" + ip.getHostAddress() + "%" + ifIndex;
+        if (DBG) { Log.d(TAG, msgSnippet); }
+
+        final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage(
+                1, ip, StructNdMsg.NUD_PROBE, ifIndex, null);
+
+        try {
+            NetlinkSocket.sendOneShotKernelMessage(OsConstants.NETLINK_ROUTE, msg);
+        } catch (ErrnoException e) {
+            Log.e(TAG, "Error " + msgSnippet + ": " + e);
+            return -e.errno;
+        }
+
+        return 0;
+    }
+
+    public static class NeighborEvent {
+        final long elapsedMs;
+        final short msgType;
+        final int ifindex;
+        final InetAddress ip;
+        final short nudState;
+        final MacAddress macAddr;
+
+        public NeighborEvent(long elapsedMs, short msgType, int ifindex, InetAddress ip,
+                short nudState, MacAddress macAddr) {
+            this.elapsedMs = elapsedMs;
+            this.msgType = msgType;
+            this.ifindex = ifindex;
+            this.ip = ip;
+            this.nudState = nudState;
+            this.macAddr = macAddr;
+        }
+
+        boolean isConnected() {
+            return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateConnected(nudState);
+        }
+
+        boolean isValid() {
+            return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateValid(nudState);
+        }
+
+        @Override
+        public String toString() {
+            final StringJoiner j = new StringJoiner(",", "NeighborEvent{", "}");
+            return j.add("@" + elapsedMs)
+                    .add(stringForNlMsgType(msgType))
+                    .add("if=" + ifindex)
+                    .add(ip.getHostAddress())
+                    .add(StructNdMsg.stringForNudState(nudState))
+                    .add("[" + macAddr + "]")
+                    .toString();
+        }
+    }
+
+    public interface NeighborEventConsumer {
+        // Every neighbor event received on the netlink socket is passed in
+        // here. Subclasses should filter for events of interest.
+        public void accept(NeighborEvent event);
+    }
+
+    private final SharedLog mLog;
+    private final NeighborEventConsumer mConsumer;
+
+    public IpNeighborMonitor(Handler h, SharedLog log, NeighborEventConsumer cb) {
+        super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE);
+        mLog = log.forSubComponent(TAG);
+        mConsumer = (cb != null) ? cb : (event) -> { /* discard */ };
+    }
+
+    @Override
+    protected FileDescriptor createFd() {
+        FileDescriptor fd = null;
+
+        try {
+            fd = NetlinkSocket.forProto(OsConstants.NETLINK_ROUTE);
+            Os.bind(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH));
+            NetlinkSocket.connectToKernel(fd);
+
+            if (VDBG) {
+                final SocketAddress nlAddr = Os.getsockname(fd);
+                Log.d(TAG, "bound to sockaddr_nl{" + nlAddr.toString() + "}");
+            }
+        } catch (ErrnoException|SocketException e) {
+            logError("Failed to create rtnetlink socket", e);
+            IoUtils.closeQuietly(fd);
+            return null;
+        }
+
+        return fd;
+    }
+
+    @Override
+    protected void handlePacket(byte[] recvbuf, int length) {
+        final long whenMs = SystemClock.elapsedRealtime();
+
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length);
+        byteBuffer.order(ByteOrder.nativeOrder());
+
+        parseNetlinkMessageBuffer(byteBuffer, whenMs);
+    }
+
+    private void parseNetlinkMessageBuffer(ByteBuffer byteBuffer, long whenMs) {
+        while (byteBuffer.remaining() > 0) {
+            final int position = byteBuffer.position();
+            final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer);
+            if (nlMsg == null || nlMsg.getHeader() == null) {
+                byteBuffer.position(position);
+                mLog.e("unparsable netlink msg: " + hexify(byteBuffer));
+                break;
+            }
+
+            final int srcPortId = nlMsg.getHeader().nlmsg_pid;
+            if (srcPortId !=  0) {
+                mLog.e("non-kernel source portId: " + BitUtils.uint32(srcPortId));
+                break;
+            }
+
+            if (nlMsg instanceof NetlinkErrorMessage) {
+                mLog.e("netlink error: " + nlMsg);
+                continue;
+            } else if (!(nlMsg instanceof RtNetlinkNeighborMessage)) {
+                mLog.i("non-rtnetlink neighbor msg: " + nlMsg);
+                continue;
+            }
+
+            evaluateRtNetlinkNeighborMessage((RtNetlinkNeighborMessage) nlMsg, whenMs);
+        }
+    }
+
+    private void evaluateRtNetlinkNeighborMessage(
+            RtNetlinkNeighborMessage neighMsg, long whenMs) {
+        final short msgType = neighMsg.getHeader().nlmsg_type;
+        final StructNdMsg ndMsg = neighMsg.getNdHeader();
+        if (ndMsg == null) {
+            mLog.e("RtNetlinkNeighborMessage without ND message header!");
+            return;
+        }
+
+        final int ifindex = ndMsg.ndm_ifindex;
+        final InetAddress destination = neighMsg.getDestination();
+        final short nudState =
+                (msgType == RTM_DELNEIGH)
+                ? StructNdMsg.NUD_NONE
+                : ndMsg.ndm_state;
+
+        final NeighborEvent event = new NeighborEvent(
+                whenMs, msgType, ifindex, destination, nudState,
+                getMacAddress(neighMsg.getLinkLayerAddress()));
+
+        if (VDBG) {
+            Log.d(TAG, neighMsg.toString());
+        }
+        if (DBG) {
+            Log.d(TAG, event.toString());
+        }
+
+        mConsumer.accept(event);
+    }
+
+    private static MacAddress getMacAddress(byte[] linkLayerAddress) {
+        if (linkLayerAddress != null) {
+            try {
+                return MacAddress.fromBytes(linkLayerAddress);
+            } catch (IllegalArgumentException e) {
+                Log.e(TAG, "Failed to parse link-layer address: " + hexify(linkLayerAddress));
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/src/android/net/ip/IpReachabilityMonitor.java b/src/android/net/ip/IpReachabilityMonitor.java
new file mode 100644
index 0000000..761db68
--- /dev/null
+++ b/src/android/net/ip/IpReachabilityMonitor.java
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2015 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.ip;
+
+import static android.net.metrics.IpReachabilityEvent.NUD_FAILED;
+import static android.net.metrics.IpReachabilityEvent.NUD_FAILED_ORGANIC;
+import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST;
+import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST_ORGANIC;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
+import android.net.RouteInfo;
+import android.net.ip.IpNeighborMonitor.NeighborEvent;
+import android.net.metrics.IpConnectivityLog;
+import android.net.metrics.IpReachabilityEvent;
+import android.net.netlink.StructNdMsg;
+import android.net.util.InterfaceParams;
+import android.net.util.SharedLog;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.DumpUtils.Dump;
+
+import java.io.PrintWriter;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * IpReachabilityMonitor.
+ *
+ * Monitors on-link IP reachability and notifies callers whenever any on-link
+ * addresses of interest appear to have become unresponsive.
+ *
+ * This code does not concern itself with "why" a neighbour might have become
+ * unreachable. Instead, it primarily reacts to the kernel's notion of IP
+ * reachability for each of the neighbours we know to be critically important
+ * to normal network connectivity. As such, it is often "just the messenger":
+ * the neighbours about which it warns are already deemed by the kernel to have
+ * become unreachable.
+ *
+ *
+ * How it works:
+ *
+ *   1. The "on-link neighbours of interest" found in a given LinkProperties
+ *      instance are added to a "watch list" via #updateLinkProperties().
+ *      This usually means all default gateways and any on-link DNS servers.
+ *
+ *   2. We listen continuously for netlink neighbour messages (RTM_NEWNEIGH,
+ *      RTM_DELNEIGH), watching only for neighbours in the watch list.
+ *
+ *        - A neighbour going into NUD_REACHABLE, NUD_STALE, NUD_DELAY, and
+ *          even NUD_PROBE is perfectly normal; we merely record the new state.
+ *
+ *        - A neighbour's entry may be deleted (RTM_DELNEIGH), for example due
+ *          to garbage collection.  This is not necessarily of immediate
+ *          concern; we record the neighbour as moving to NUD_NONE.
+ *
+ *        - A neighbour transitioning to NUD_FAILED (for any reason) is
+ *          critically important and is handled as described below in #4.
+ *
+ *   3. All on-link neighbours in the watch list can be forcibly "probed" by
+ *      calling #probeAll(). This should be called whenever it is important to
+ *      verify that critical neighbours on the link are still reachable, e.g.
+ *      when roaming between BSSIDs.
+ *
+ *        - The kernel will send unicast ARP requests for IPv4 neighbours and
+ *          unicast NS packets for IPv6 neighbours.  The expected replies will
+ *          likely be unicast.
+ *
+ *        - The forced probing is done holding a wakelock. The kernel may,
+ *          however, initiate probing of a neighbor on its own, i.e. whenever
+ *          a neighbour has expired from NUD_DELAY.
+ *
+ *        - The kernel sends:
+ *
+ *              /proc/sys/net/ipv{4,6}/neigh/<ifname>/ucast_solicit
+ *
+ *          number of probes (usually 3) every:
+ *
+ *              /proc/sys/net/ipv{4,6}/neigh/<ifname>/retrans_time_ms
+ *
+ *          number of milliseconds (usually 1000ms). This normally results in
+ *          3 unicast packets, 1 per second.
+ *
+ *        - If no response is received to any of the probe packets, the kernel
+ *          marks the neighbour as being in state NUD_FAILED, and the listening
+ *          process in #2 will learn of it.
+ *
+ *   4. We call the supplied Callback#notifyLost() function if the loss of a
+ *      neighbour in NUD_FAILED would cause IPv4 or IPv6 configuration to
+ *      become incomplete (a loss of provisioning).
+ *
+ *        - For example, losing all our IPv4 on-link DNS servers (or losing
+ *          our only IPv6 default gateway) constitutes a loss of IPv4 (IPv6)
+ *          provisioning; Callback#notifyLost() would be called.
+ *
+ *        - Since it can be non-trivial to reacquire certain IP provisioning
+ *          state it may be best for the link to disconnect completely and
+ *          reconnect afresh.
+ *
+ * Accessing an instance of this class from multiple threads is NOT safe.
+ *
+ * @hide
+ */
+public class IpReachabilityMonitor {
+    private static final String TAG = "IpReachabilityMonitor";
+    private static final boolean DBG = false;
+    private static final boolean VDBG = false;
+
+    public interface Callback {
+        // This callback function must execute as quickly as possible as it is
+        // run on the same thread that listens to kernel neighbor updates.
+        //
+        // TODO: refactor to something like notifyProvisioningLost(String msg).
+        public void notifyLost(InetAddress ip, String logMsg);
+    }
+
+    /**
+     * Encapsulates IpReachabilityMonitor depencencies on systems that hinder unit testing.
+     * TODO: consider also wrapping MultinetworkPolicyTracker in this interface.
+     */
+    interface Dependencies {
+        void acquireWakeLock(long durationMs);
+
+        static Dependencies makeDefault(Context context, String iface) {
+            final String lockName = TAG + "." + iface;
+            final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+            final WakeLock lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
+
+            return new Dependencies() {
+                public void acquireWakeLock(long durationMs) {
+                    lock.acquire(durationMs);
+                }
+            };
+        }
+    }
+
+    private final InterfaceParams mInterfaceParams;
+    private final IpNeighborMonitor mIpNeighborMonitor;
+    private final SharedLog mLog;
+    private final Callback mCallback;
+    private final Dependencies mDependencies;
+    private final boolean mUsingMultinetworkPolicyTracker;
+    private final ConnectivityManager mCm;
+    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
+    private LinkProperties mLinkProperties = new LinkProperties();
+    private Map<InetAddress, NeighborEvent> mNeighborWatchList = new HashMap<>();
+    // Time in milliseconds of the last forced probe request.
+    private volatile long mLastProbeTimeMs;
+
+    public IpReachabilityMonitor(
+            Context context, InterfaceParams ifParams, Handler h, SharedLog log, Callback callback,
+            boolean usingMultinetworkPolicyTracker) {
+        this(context, ifParams, h, log, callback, usingMultinetworkPolicyTracker,
+                Dependencies.makeDefault(context, ifParams.name));
+    }
+
+    @VisibleForTesting
+    IpReachabilityMonitor(Context context, InterfaceParams ifParams, Handler h, SharedLog log,
+            Callback callback, boolean usingMultinetworkPolicyTracker, Dependencies dependencies) {
+        if (ifParams == null) throw new IllegalArgumentException("null InterfaceParams");
+
+        mInterfaceParams = ifParams;
+        mLog = log.forSubComponent(TAG);
+        mCallback = callback;
+        mUsingMultinetworkPolicyTracker = usingMultinetworkPolicyTracker;
+        mCm = context.getSystemService(ConnectivityManager.class);
+        mDependencies = dependencies;
+
+        mIpNeighborMonitor = new IpNeighborMonitor(h, mLog,
+                (NeighborEvent event) -> {
+                    if (mInterfaceParams.index != event.ifindex) return;
+                    if (!mNeighborWatchList.containsKey(event.ip)) return;
+
+                    final NeighborEvent prev = mNeighborWatchList.put(event.ip, event);
+
+                    // TODO: Consider what to do with other states that are not within
+                    // NeighborEvent#isValid() (i.e. NUD_NONE, NUD_INCOMPLETE).
+                    if (event.nudState == StructNdMsg.NUD_FAILED) {
+                        mLog.w("ALERT neighbor went from: " + prev + " to: " + event);
+                        handleNeighborLost(event);
+                    }
+                });
+        mIpNeighborMonitor.start();
+    }
+
+    public void stop() {
+        mIpNeighborMonitor.stop();
+        clearLinkProperties();
+    }
+
+    public void dump(PrintWriter pw) {
+        DumpUtils.dumpAsync(
+                mIpNeighborMonitor.getHandler(),
+                new Dump() {
+                    @Override
+                    public void dump(PrintWriter pw, String prefix) {
+                        pw.println(describeWatchList("\n"));
+                    }
+                },
+                pw, "", 1000);
+    }
+
+    private String describeWatchList() { return describeWatchList(" "); }
+
+    private String describeWatchList(String sep) {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("iface{" + mInterfaceParams + "}," + sep);
+        sb.append("ntable=[" + sep);
+        String delimiter = "";
+        for (Map.Entry<InetAddress, NeighborEvent> entry : mNeighborWatchList.entrySet()) {
+            sb.append(delimiter).append(entry.getKey().getHostAddress() + "/" + entry.getValue());
+            delimiter = "," + sep;
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    private static boolean isOnLink(List<RouteInfo> routes, InetAddress ip) {
+        for (RouteInfo route : routes) {
+            if (!route.hasGateway() && route.matches(ip)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void updateLinkProperties(LinkProperties lp) {
+        if (!mInterfaceParams.name.equals(lp.getInterfaceName())) {
+            // TODO: figure out whether / how to cope with interface changes.
+            Log.wtf(TAG, "requested LinkProperties interface '" + lp.getInterfaceName() +
+                    "' does not match: " + mInterfaceParams.name);
+            return;
+        }
+
+        mLinkProperties = new LinkProperties(lp);
+        Map<InetAddress, NeighborEvent> newNeighborWatchList = new HashMap<>();
+
+        final List<RouteInfo> routes = mLinkProperties.getRoutes();
+        for (RouteInfo route : routes) {
+            if (route.hasGateway()) {
+                InetAddress gw = route.getGateway();
+                if (isOnLink(routes, gw)) {
+                    newNeighborWatchList.put(gw, mNeighborWatchList.getOrDefault(gw, null));
+                }
+            }
+        }
+
+        for (InetAddress dns : lp.getDnsServers()) {
+            if (isOnLink(routes, dns)) {
+                newNeighborWatchList.put(dns, mNeighborWatchList.getOrDefault(dns, null));
+            }
+        }
+
+        mNeighborWatchList = newNeighborWatchList;
+        if (DBG) { Log.d(TAG, "watch: " + describeWatchList()); }
+    }
+
+    public void clearLinkProperties() {
+        mLinkProperties.clear();
+        mNeighborWatchList.clear();
+        if (DBG) { Log.d(TAG, "clear: " + describeWatchList()); }
+    }
+
+    private void handleNeighborLost(NeighborEvent event) {
+        final LinkProperties whatIfLp = new LinkProperties(mLinkProperties);
+
+        InetAddress ip = null;
+        for (Map.Entry<InetAddress, NeighborEvent> entry : mNeighborWatchList.entrySet()) {
+            // TODO: Consider using NeighborEvent#isValid() here; it's more
+            // strict but may interact badly if other entries are somehow in
+            // NUD_INCOMPLETE (say, during network attach).
+            if (entry.getValue().nudState != StructNdMsg.NUD_FAILED) continue;
+
+            ip = entry.getKey();
+            for (RouteInfo route : mLinkProperties.getRoutes()) {
+                if (ip.equals(route.getGateway())) {
+                    whatIfLp.removeRoute(route);
+                }
+            }
+
+            if (avoidingBadLinks() || !(ip instanceof Inet6Address)) {
+                // We should do this unconditionally, but alas we cannot: b/31827713.
+                whatIfLp.removeDnsServer(ip);
+            }
+        }
+
+        final boolean lostProvisioning =
+                (mLinkProperties.isIPv4Provisioned() && !whatIfLp.isIPv4Provisioned())
+                || (mLinkProperties.isIPv6Provisioned() && !whatIfLp.isIPv6Provisioned());
+
+        if (lostProvisioning) {
+            final String logMsg = "FAILURE: LOST_PROVISIONING, " + event;
+            Log.w(TAG, logMsg);
+            if (mCallback != null) {
+                // TODO: remove |ip| when the callback signature no longer has
+                // an InetAddress argument.
+                mCallback.notifyLost(ip, logMsg);
+            }
+        }
+        logNudFailed(lostProvisioning);
+    }
+
+    private boolean avoidingBadLinks() {
+        return !mUsingMultinetworkPolicyTracker || mCm.getAvoidBadWifi();
+    }
+
+    public void probeAll() {
+        final List<InetAddress> ipProbeList = new ArrayList<>(mNeighborWatchList.keySet());
+
+        if (!ipProbeList.isEmpty()) {
+            // Keep the CPU awake long enough to allow all ARP/ND
+            // probes a reasonable chance at success. See b/23197666.
+            //
+            // The wakelock we use is (by default) refcounted, and this version
+            // of acquire(timeout) queues a release message to keep acquisitions
+            // and releases balanced.
+            mDependencies.acquireWakeLock(getProbeWakeLockDuration());
+        }
+
+        for (InetAddress ip : ipProbeList) {
+            final int rval = IpNeighborMonitor.startKernelNeighborProbe(mInterfaceParams.index, ip);
+            mLog.log(String.format("put neighbor %s into NUD_PROBE state (rval=%d)",
+                     ip.getHostAddress(), rval));
+            logEvent(IpReachabilityEvent.PROBE, rval);
+        }
+        mLastProbeTimeMs = SystemClock.elapsedRealtime();
+    }
+
+    private static long getProbeWakeLockDuration() {
+        // Ideally, this would be computed by examining the values of:
+        //
+        //     /proc/sys/net/ipv[46]/neigh/<ifname>/ucast_solicit
+        //
+        // and:
+        //
+        //     /proc/sys/net/ipv[46]/neigh/<ifname>/retrans_time_ms
+        //
+        // For now, just make some assumptions.
+        final long numUnicastProbes = 3;
+        final long retransTimeMs = 1000;
+        final long gracePeriodMs = 500;
+        return (numUnicastProbes * retransTimeMs) + gracePeriodMs;
+    }
+
+    private void logEvent(int probeType, int errorCode) {
+        int eventType = probeType | (errorCode & 0xff);
+        mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
+    }
+
+    private void logNudFailed(boolean lostProvisioning) {
+        long duration = SystemClock.elapsedRealtime() - mLastProbeTimeMs;
+        boolean isFromProbe = (duration < getProbeWakeLockDuration());
+        int eventType = nudFailureEventType(isFromProbe, lostProvisioning);
+        mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
+    }
+
+    /**
+     * Returns the NUD failure event type code corresponding to the given conditions.
+     */
+    private static int nudFailureEventType(boolean isFromProbe, boolean isProvisioningLost) {
+        if (isFromProbe) {
+            return isProvisioningLost ? PROVISIONING_LOST : NUD_FAILED;
+        } else {
+            return isProvisioningLost ? PROVISIONING_LOST_ORGANIC : NUD_FAILED_ORGANIC;
+        }
+    }
+}
diff --git a/src/android/net/util/ConnectivityPacketSummary.java b/src/android/net/util/ConnectivityPacketSummary.java
new file mode 100644
index 0000000..08c3f60
--- /dev/null
+++ b/src/android/net/util/ConnectivityPacketSummary.java
@@ -0,0 +1,435 @@
+/*
+ * 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.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_UDP;
+
+import static com.android.server.util.NetworkStackConstants.ARP_HWTYPE_ETHER;
+import static com.android.server.util.NetworkStackConstants.ARP_PAYLOAD_LEN;
+import static com.android.server.util.NetworkStackConstants.ARP_REPLY;
+import static com.android.server.util.NetworkStackConstants.ARP_REQUEST;
+import static com.android.server.util.NetworkStackConstants.DHCP4_CLIENT_PORT;
+import static com.android.server.util.NetworkStackConstants.ETHER_ADDR_LEN;
+import static com.android.server.util.NetworkStackConstants.ETHER_DST_ADDR_OFFSET;
+import static com.android.server.util.NetworkStackConstants.ETHER_HEADER_LEN;
+import static com.android.server.util.NetworkStackConstants.ETHER_SRC_ADDR_OFFSET;
+import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_ARP;
+import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV4;
+import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV6;
+import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_OFFSET;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_HEADER_MIN_LEN;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MIN_LENGTH;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MTU;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
+import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_LEN;
+import static com.android.server.util.NetworkStackConstants.IPV4_DST_ADDR_OFFSET;
+import static com.android.server.util.NetworkStackConstants.IPV4_FLAGS_OFFSET;
+import static com.android.server.util.NetworkStackConstants.IPV4_FRAGMENT_MASK;
+import static com.android.server.util.NetworkStackConstants.IPV4_HEADER_MIN_LEN;
+import static com.android.server.util.NetworkStackConstants.IPV4_IHL_MASK;
+import static com.android.server.util.NetworkStackConstants.IPV4_PROTOCOL_OFFSET;
+import static com.android.server.util.NetworkStackConstants.IPV4_SRC_ADDR_OFFSET;
+import static com.android.server.util.NetworkStackConstants.IPV6_ADDR_LEN;
+import static com.android.server.util.NetworkStackConstants.IPV6_HEADER_LEN;
+import static com.android.server.util.NetworkStackConstants.IPV6_PROTOCOL_OFFSET;
+import static com.android.server.util.NetworkStackConstants.IPV6_SRC_ADDR_OFFSET;
+import static com.android.server.util.NetworkStackConstants.UDP_HEADER_LEN;
+
+import android.net.MacAddress;
+import android.net.dhcp.DhcpPacket;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.StringJoiner;
+
+
+/**
+ * Critical connectivity packet summarizing class.
+ *
+ * Outputs short descriptions of ARP, DHCPv4, and IPv6 RS/RA/NS/NA packets.
+ *
+ * @hide
+ */
+public class ConnectivityPacketSummary {
+    private static final String TAG = ConnectivityPacketSummary.class.getSimpleName();
+
+    private final byte[] mHwAddr;
+    private final byte[] mBytes;
+    private final int mLength;
+    private final ByteBuffer mPacket;
+    private final String mSummary;
+
+    public static String summarize(MacAddress hwaddr, byte[] buffer) {
+        return summarize(hwaddr, buffer, buffer.length);
+    }
+
+    // Methods called herein perform some but by no means all error checking.
+    // They may throw runtime exceptions on malformed packets.
+    public static String summarize(MacAddress macAddr, byte[] buffer, int length) {
+        if ((macAddr == null) || (buffer == null)) return null;
+        length = Math.min(length, buffer.length);
+        return (new ConnectivityPacketSummary(macAddr, buffer, length)).toString();
+    }
+
+    private ConnectivityPacketSummary(MacAddress macAddr, byte[] buffer, int length) {
+        mHwAddr = macAddr.toByteArray();
+        mBytes = buffer;
+        mLength = Math.min(length, mBytes.length);
+        mPacket = ByteBuffer.wrap(mBytes, 0, mLength);
+        mPacket.order(ByteOrder.BIG_ENDIAN);
+
+        final StringJoiner sj = new StringJoiner(" ");
+        // TODO: support other link-layers, or even no link-layer header.
+        parseEther(sj);
+        mSummary = sj.toString();
+    }
+
+    public String toString() {
+        return mSummary;
+    }
+
+    private void parseEther(StringJoiner sj) {
+        if (mPacket.remaining() < ETHER_HEADER_LEN) {
+            sj.add("runt:").add(asString(mPacket.remaining()));
+            return;
+        }
+
+        mPacket.position(ETHER_SRC_ADDR_OFFSET);
+        final ByteBuffer srcMac = (ByteBuffer) mPacket.slice().limit(ETHER_ADDR_LEN);
+        sj.add(ByteBuffer.wrap(mHwAddr).equals(srcMac) ? "TX" : "RX");
+        sj.add(getMacAddressString(srcMac));
+
+        mPacket.position(ETHER_DST_ADDR_OFFSET);
+        final ByteBuffer dstMac = (ByteBuffer) mPacket.slice().limit(ETHER_ADDR_LEN);
+        sj.add(">").add(getMacAddressString(dstMac));
+
+        mPacket.position(ETHER_TYPE_OFFSET);
+        final int etherType = asUint(mPacket.getShort());
+        switch (etherType) {
+            case ETHER_TYPE_ARP:
+                sj.add("arp");
+                parseARP(sj);
+                break;
+            case ETHER_TYPE_IPV4:
+                sj.add("ipv4");
+                parseIPv4(sj);
+                break;
+            case ETHER_TYPE_IPV6:
+                sj.add("ipv6");
+                parseIPv6(sj);
+                break;
+            default:
+                // Unknown ether type.
+                sj.add("ethtype").add(asString(etherType));
+                break;
+        }
+    }
+
+    private void parseARP(StringJoiner sj) {
+        if (mPacket.remaining() < ARP_PAYLOAD_LEN) {
+            sj.add("runt:").add(asString(mPacket.remaining()));
+            return;
+        }
+
+        if (asUint(mPacket.getShort()) != ARP_HWTYPE_ETHER ||
+            asUint(mPacket.getShort()) != ETHER_TYPE_IPV4 ||
+            asUint(mPacket.get()) != ETHER_ADDR_LEN ||
+            asUint(mPacket.get()) != IPV4_ADDR_LEN) {
+            sj.add("unexpected header");
+            return;
+        }
+
+        final int opCode = asUint(mPacket.getShort());
+
+        final String senderHwAddr = getMacAddressString(mPacket);
+        final String senderIPv4 = getIPv4AddressString(mPacket);
+        getMacAddressString(mPacket);  // target hardware address, unused
+        final String targetIPv4 = getIPv4AddressString(mPacket);
+
+        if (opCode == ARP_REQUEST) {
+            sj.add("who-has").add(targetIPv4);
+        } else if (opCode == ARP_REPLY) {
+            sj.add("reply").add(senderIPv4).add(senderHwAddr);
+        } else {
+            sj.add("unknown opcode").add(asString(opCode));
+        }
+    }
+
+    private void parseIPv4(StringJoiner sj) {
+        if (!mPacket.hasRemaining()) {
+            sj.add("runt");
+            return;
+        }
+
+        final int startOfIpLayer = mPacket.position();
+        final int ipv4HeaderLength = (mPacket.get(startOfIpLayer) & IPV4_IHL_MASK) * 4;
+        if (mPacket.remaining() < ipv4HeaderLength ||
+            mPacket.remaining() < IPV4_HEADER_MIN_LEN) {
+            sj.add("runt:").add(asString(mPacket.remaining()));
+            return;
+        }
+        final int startOfTransportLayer = startOfIpLayer + ipv4HeaderLength;
+
+        mPacket.position(startOfIpLayer + IPV4_FLAGS_OFFSET);
+        final int flagsAndFragment = asUint(mPacket.getShort());
+        final boolean isFragment = (flagsAndFragment & IPV4_FRAGMENT_MASK) != 0;
+
+        mPacket.position(startOfIpLayer + IPV4_PROTOCOL_OFFSET);
+        final int protocol = asUint(mPacket.get());
+
+        mPacket.position(startOfIpLayer + IPV4_SRC_ADDR_OFFSET);
+        final String srcAddr = getIPv4AddressString(mPacket);
+
+        mPacket.position(startOfIpLayer + IPV4_DST_ADDR_OFFSET);
+        final String dstAddr = getIPv4AddressString(mPacket);
+
+        sj.add(srcAddr).add(">").add(dstAddr);
+
+        mPacket.position(startOfTransportLayer);
+        if (protocol == IPPROTO_UDP) {
+            sj.add("udp");
+            if (isFragment) sj.add("fragment");
+            else parseUDP(sj);
+        } else {
+            sj.add("proto").add(asString(protocol));
+            if (isFragment) sj.add("fragment");
+        }
+    }
+
+    private void parseIPv6(StringJoiner sj) {
+        if (mPacket.remaining() < IPV6_HEADER_LEN) {
+            sj.add("runt:").add(asString(mPacket.remaining()));
+            return;
+        }
+
+        final int startOfIpLayer = mPacket.position();
+
+        mPacket.position(startOfIpLayer + IPV6_PROTOCOL_OFFSET);
+        final int protocol = asUint(mPacket.get());
+
+        mPacket.position(startOfIpLayer + IPV6_SRC_ADDR_OFFSET);
+        final String srcAddr = getIPv6AddressString(mPacket);
+        final String dstAddr = getIPv6AddressString(mPacket);
+
+        sj.add(srcAddr).add(">").add(dstAddr);
+
+        mPacket.position(startOfIpLayer + IPV6_HEADER_LEN);
+        if (protocol == IPPROTO_ICMPV6) {
+            sj.add("icmp6");
+            parseICMPv6(sj);
+        } else {
+            sj.add("proto").add(asString(protocol));
+        }
+    }
+
+    private void parseICMPv6(StringJoiner sj) {
+        if (mPacket.remaining() < ICMPV6_HEADER_MIN_LEN) {
+            sj.add("runt:").add(asString(mPacket.remaining()));
+            return;
+        }
+
+        final int icmp6Type = asUint(mPacket.get());
+        final int icmp6Code = asUint(mPacket.get());
+        mPacket.getShort();  // checksum, unused
+
+        switch (icmp6Type) {
+            case ICMPV6_ROUTER_SOLICITATION:
+                sj.add("rs");
+                parseICMPv6RouterSolicitation(sj);
+                break;
+            case ICMPV6_ROUTER_ADVERTISEMENT:
+                sj.add("ra");
+                parseICMPv6RouterAdvertisement(sj);
+                break;
+            case ICMPV6_NEIGHBOR_SOLICITATION:
+                sj.add("ns");
+                parseICMPv6NeighborMessage(sj);
+                break;
+            case ICMPV6_NEIGHBOR_ADVERTISEMENT:
+                sj.add("na");
+                parseICMPv6NeighborMessage(sj);
+                break;
+            default:
+                sj.add("type").add(asString(icmp6Type));
+                sj.add("code").add(asString(icmp6Code));
+                break;
+        }
+    }
+
+    private void parseICMPv6RouterSolicitation(StringJoiner sj) {
+        final int RESERVED = 4;
+        if (mPacket.remaining() < RESERVED) {
+            sj.add("runt:").add(asString(mPacket.remaining()));
+            return;
+        }
+
+        mPacket.position(mPacket.position() + RESERVED);
+        parseICMPv6NeighborDiscoveryOptions(sj);
+    }
+
+    private void parseICMPv6RouterAdvertisement(StringJoiner sj) {
+        final int FLAGS_AND_TIMERS = 3 * 4;
+        if (mPacket.remaining() < FLAGS_AND_TIMERS) {
+            sj.add("runt:").add(asString(mPacket.remaining()));
+            return;
+        }
+
+        mPacket.position(mPacket.position() + FLAGS_AND_TIMERS);
+        parseICMPv6NeighborDiscoveryOptions(sj);
+    }
+
+    private void parseICMPv6NeighborMessage(StringJoiner sj) {
+        final int RESERVED = 4;
+        final int minReq = RESERVED + IPV6_ADDR_LEN;
+        if (mPacket.remaining() < minReq) {
+            sj.add("runt:").add(asString(mPacket.remaining()));
+            return;
+        }
+
+        mPacket.position(mPacket.position() + RESERVED);
+        sj.add(getIPv6AddressString(mPacket));
+        parseICMPv6NeighborDiscoveryOptions(sj);
+    }
+
+    private void parseICMPv6NeighborDiscoveryOptions(StringJoiner sj) {
+        // All ND options are TLV, where T is one byte and L is one byte equal
+        // to the length of T + L + V in units of 8 octets.
+        while (mPacket.remaining() >= ICMPV6_ND_OPTION_MIN_LENGTH) {
+            final int ndType = asUint(mPacket.get());
+            final int ndLength = asUint(mPacket.get());
+            final int ndBytes = ndLength * ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR - 2;
+            if (ndBytes < 0 || ndBytes > mPacket.remaining()) {
+                sj.add("<malformed>");
+                break;
+            }
+            final int position = mPacket.position();
+
+            switch (ndType) {
+                    case ICMPV6_ND_OPTION_SLLA:
+                        sj.add("slla");
+                        sj.add(getMacAddressString(mPacket));
+                        break;
+                    case ICMPV6_ND_OPTION_TLLA:
+                        sj.add("tlla");
+                        sj.add(getMacAddressString(mPacket));
+                        break;
+                    case ICMPV6_ND_OPTION_MTU:
+                        sj.add("mtu");
+                        final short reserved = mPacket.getShort();
+                        sj.add(asString(mPacket.getInt()));
+                        break;
+                    default:
+                        // Skip.
+                        break;
+            }
+
+            mPacket.position(position + ndBytes);
+        }
+    }
+
+    private void parseUDP(StringJoiner sj) {
+        if (mPacket.remaining() < UDP_HEADER_LEN) {
+            sj.add("runt:").add(asString(mPacket.remaining()));
+            return;
+        }
+
+        final int previous = mPacket.position();
+        final int srcPort = asUint(mPacket.getShort());
+        final int dstPort = asUint(mPacket.getShort());
+        sj.add(asString(srcPort)).add(">").add(asString(dstPort));
+
+        mPacket.position(previous + UDP_HEADER_LEN);
+        if (srcPort == DHCP4_CLIENT_PORT || dstPort == DHCP4_CLIENT_PORT) {
+            sj.add("dhcp4");
+            parseDHCPv4(sj);
+        }
+    }
+
+    private void parseDHCPv4(StringJoiner sj) {
+        final DhcpPacket dhcpPacket;
+        try {
+            dhcpPacket = DhcpPacket.decodeFullPacket(mBytes, mLength, DhcpPacket.ENCAP_L2);
+            sj.add(dhcpPacket.toString());
+        } catch (DhcpPacket.ParseException e) {
+            sj.add("parse error: " + e);
+        }
+    }
+
+    private static String getIPv4AddressString(ByteBuffer ipv4) {
+        return getIpAddressString(ipv4, IPV4_ADDR_LEN);
+    }
+
+    private static String getIPv6AddressString(ByteBuffer ipv6) {
+        return getIpAddressString(ipv6, IPV6_ADDR_LEN);
+    }
+
+    private static String getIpAddressString(ByteBuffer ip, int byteLength) {
+        if (ip == null || ip.remaining() < byteLength) return "invalid";
+
+        byte[] bytes = new byte[byteLength];
+        ip.get(bytes, 0, byteLength);
+        try {
+            InetAddress addr = InetAddress.getByAddress(bytes);
+            return addr.getHostAddress();
+        } catch (UnknownHostException uhe) {
+            return "unknown";
+        }
+    }
+
+    private static String getMacAddressString(ByteBuffer mac) {
+        if (mac == null || mac.remaining() < ETHER_ADDR_LEN) return "invalid";
+
+        byte[] bytes = new byte[ETHER_ADDR_LEN];
+        mac.get(bytes, 0, bytes.length);
+        Object[] printableBytes = new Object[bytes.length];
+        int i = 0;
+        for (byte b : bytes) printableBytes[i++] = new Byte(b);
+
+        final String MAC48_FORMAT = "%02x:%02x:%02x:%02x:%02x:%02x";
+        return String.format(MAC48_FORMAT, printableBytes);
+    }
+
+    /**
+     * Convenience method to convert an int to a String.
+     */
+    public static String asString(int i) {
+        return Integer.toString(i);
+    }
+
+    /**
+     * Convenience method to read a byte as an unsigned int.
+     */
+    public static int asUint(byte b) {
+        return (b & 0xff);
+    }
+
+    /**
+     * Convenience method to read a short as an unsigned int.
+     */
+    public static int asUint(short s) {
+        return (s & 0xffff);
+    }
+}
diff --git a/src/android/net/util/FdEventsReader.java b/src/android/net/util/FdEventsReader.java
new file mode 100644
index 0000000..8bbf449
--- /dev/null
+++ b/src/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 void start() {
+        if (onCorrectThread()) {
+            createAndRegisterFd();
+        } else {
+            mHandler.post(() -> {
+                logError("start() called from off-thread", null);
+                createAndRegisterFd();
+            });
+        }
+    }
+
+    public 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/src/android/net/util/PacketReader.java b/src/android/net/util/PacketReader.java
new file mode 100644
index 0000000..4aec6b6
--- /dev/null
+++ b/src/android/net/util/PacketReader.java
@@ -0,0 +1,61 @@
+/*
+ * 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.util;
+
+import static java.lang.Math.max;
+
+import android.os.Handler;
+import android.system.Os;
+
+import java.io.FileDescriptor;
+
+/**
+ * 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 extends FdEventsReader<byte[]> {
+
+    public static final int DEFAULT_RECV_BUF_SIZE = 2 * 1024;
+
+    protected PacketReader(Handler h) {
+        this(h, DEFAULT_RECV_BUF_SIZE);
+    }
+
+    protected PacketReader(Handler h, int recvBufSize) {
+        super(h, new byte[max(recvBufSize, DEFAULT_RECV_BUF_SIZE)]);
+    }
+
+    @Override
+    protected final int recvBufSize(byte[] buffer) {
+        return buffer.length;
+    }
+
+    /**
+     * 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);
+    }
+}
diff --git a/src/com/android/server/NetworkStackService.java b/src/com/android/server/NetworkStackService.java
index cca71e7..4080ddf 100644
--- a/src/com/android/server/NetworkStackService.java
+++ b/src/com/android/server/NetworkStackService.java
@@ -39,6 +39,8 @@
 import android.net.dhcp.DhcpServingParams;
 import android.net.dhcp.DhcpServingParamsParcel;
 import android.net.dhcp.IDhcpServerCallbacks;
+import android.net.ip.IIpClientCallbacks;
+import android.net.ip.IpClient;
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.SharedLog;
 import android.os.IBinder;
@@ -50,7 +52,11 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
 import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
 
 /**
  * Android service used to start the network stack when bound to via an intent.
@@ -80,6 +86,8 @@
         private static final int NUM_VALIDATION_LOG_LINES = 20;
         private final Context mContext;
         private final ConnectivityManager mCm;
+        @GuardedBy("mIpClients")
+        private final ArrayList<WeakReference<IpClient>> mIpClients = new ArrayList<>();
 
         private static final int MAX_VALIDATION_LOGS = 10;
         @GuardedBy("mValidationLogs")
@@ -138,6 +146,24 @@
         }
 
         @Override
+        public void makeIpClient(String ifName, IIpClientCallbacks cb) throws RemoteException {
+            final IpClient ipClient = new IpClient(mContext, ifName, cb);
+
+            synchronized (mIpClients) {
+                final Iterator<WeakReference<IpClient>> it = mIpClients.iterator();
+                while (it.hasNext()) {
+                    final IpClient ipc = it.next().get();
+                    if (ipc == null) {
+                        it.remove();
+                    }
+                }
+                mIpClients.add(new WeakReference<>(ipClient));
+            }
+
+            cb.onIpClientCreated(ipClient.makeConnector());
+        }
+
+        @Override
         protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
                 @Nullable String[] args) {
             checkDumpPermission();
@@ -145,6 +171,33 @@
             pw.println("NetworkStack logs:");
             mLog.dump(fd, pw, args);
 
+            // Dump full IpClient logs for non-GCed clients
+            pw.println();
+            pw.println("Recently active IpClient logs:");
+            final ArrayList<IpClient> ipClients = new ArrayList<>();
+            final HashSet<String> dumpedIpClientIfaces = new HashSet<>();
+            synchronized (mIpClients) {
+                for (WeakReference<IpClient> ipcRef : mIpClients) {
+                    final IpClient ipc = ipcRef.get();
+                    if (ipc != null) {
+                        ipClients.add(ipc);
+                    }
+                }
+            }
+
+            for (IpClient ipc : ipClients) {
+                pw.println(ipc.getName());
+                pw.increaseIndent();
+                ipc.dump(fd, pw, args);
+                pw.decreaseIndent();
+                dumpedIpClientIfaces.add(ipc.getInterfaceName());
+            }
+
+            // State machine and connectivity metrics logs are kept for GCed IpClients
+            pw.println();
+            pw.println("Other IpClient logs:");
+            IpClient.dumpAllLogs(fout, dumpedIpClientIfaces);
+
             pw.println();
             pw.println("Validation logs (most recent first):");
             synchronized (mValidationLogs) {
diff --git a/src/com/android/server/util/NetworkStackConstants.java b/src/com/android/server/util/NetworkStackConstants.java
index bb5900c..eedaf30 100644
--- a/src/com/android/server/util/NetworkStackConstants.java
+++ b/src/com/android/server/util/NetworkStackConstants.java
@@ -32,12 +32,103 @@
     public static final int IPV4_MAX_MTU = 65_535;
 
     /**
+     * Ethernet constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc894
+     *     - https://tools.ietf.org/html/rfc2464
+     *     - https://tools.ietf.org/html/rfc7042
+     *     - http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
+     *     - http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml
+     */
+    public static final int ETHER_DST_ADDR_OFFSET = 0;
+    public static final int ETHER_SRC_ADDR_OFFSET = 6;
+    public static final int ETHER_ADDR_LEN = 6;
+    public static final int ETHER_TYPE_OFFSET = 12;
+    public static final int ETHER_TYPE_LENGTH = 2;
+    public static final int ETHER_TYPE_ARP  = 0x0806;
+    public static final int ETHER_TYPE_IPV4 = 0x0800;
+    public static final int ETHER_TYPE_IPV6 = 0x86dd;
+    public static final int ETHER_HEADER_LEN = 14;
+
+    /**
+     * ARP constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc826
+     *     - http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
+     */
+    public static final int ARP_PAYLOAD_LEN = 28;  // For Ethernet+IPv4.
+    public static final int ARP_REQUEST = 1;
+    public static final int ARP_REPLY   = 2;
+    public static final int ARP_HWTYPE_RESERVED_LO = 0;
+    public static final int ARP_HWTYPE_ETHER       = 1;
+    public static final int ARP_HWTYPE_RESERVED_HI = 0xffff;
+
+    /**
+     * IPv4 constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc791
+     */
+    public static final int IPV4_HEADER_MIN_LEN = 20;
+    public static final int IPV4_IHL_MASK = 0xf;
+    public static final int IPV4_FLAGS_OFFSET = 6;
+    public static final int IPV4_FRAGMENT_MASK = 0x1fff;
+    public static final int IPV4_PROTOCOL_OFFSET = 9;
+    public static final int IPV4_SRC_ADDR_OFFSET = 12;
+    public static final int IPV4_DST_ADDR_OFFSET = 16;
+    public static final int IPV4_ADDR_LEN = 4;
+
+    /**
+     * IPv6 constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc2460
+     */
+    public static final int IPV6_ADDR_LEN = 16;
+    public static final int IPV6_HEADER_LEN = 40;
+    public static final int IPV6_PROTOCOL_OFFSET = 6;
+    public static final int IPV6_SRC_ADDR_OFFSET = 8;
+    public static final int IPV6_DST_ADDR_OFFSET = 24;
+
+    /**
+     * ICMPv6 constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc4443
+     *     - https://tools.ietf.org/html/rfc4861
+     */
+    public static final int ICMPV6_HEADER_MIN_LEN = 4;
+    public static final int ICMPV6_ECHO_REPLY_TYPE = 129;
+    public static final int ICMPV6_ECHO_REQUEST_TYPE = 128;
+    public static final int ICMPV6_ROUTER_SOLICITATION    = 133;
+    public static final int ICMPV6_ROUTER_ADVERTISEMENT   = 134;
+    public static final int ICMPV6_NEIGHBOR_SOLICITATION  = 135;
+    public static final int ICMPV6_NEIGHBOR_ADVERTISEMENT = 136;
+    public static final int ICMPV6_ND_OPTION_MIN_LENGTH = 8;
+    public static final int ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR = 8;
+    public static final int ICMPV6_ND_OPTION_SLLA = 1;
+    public static final int ICMPV6_ND_OPTION_TLLA = 2;
+    public static final int ICMPV6_ND_OPTION_MTU  = 5;
+
+    /**
+     * UDP constants.
+     *
+     * See also:
+     *     - https://tools.ietf.org/html/rfc768
+     */
+    public static final int UDP_HEADER_LEN = 8;
+
+
+    /**
      * DHCP constants.
      *
      * See also:
      *     - https://tools.ietf.org/html/rfc2131
      */
     public static final int INFINITE_LEASE = 0xffffffff;
+    public static final int DHCP4_CLIENT_PORT = 68;
 
     private NetworkStackConstants() {
         throw new UnsupportedOperationException("This class is not to be instantiated");
diff --git a/tests/Android.bp b/tests/Android.bp
index bd7ff2a..45fa2dc 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -16,9 +16,12 @@
 
 android_test {
     name: "NetworkStackTests",
+    certificate: "platform",
     srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
     static_libs: [
         "android-support-test",
+        "frameworks-base-testutils",
         "mockito-target-extended-minus-junit4",
         "NetworkStackLib",
         "testables",
@@ -26,10 +29,70 @@
     libs: [
         "android.test.runner",
         "android.test.base",
+        "android.test.mock",
     ],
     jni_libs: [
         // For mockito extended
         "libdexmakerjvmtiagent",
         "libstaticjvmtiagent",
-    ]
-}
\ No newline at end of file
+        // For ApfTest
+        "libartbase",
+        "libbacktrace",
+        "libbase",
+        "libbinder",
+        "libbinderthreadstate",
+        "libc++",
+        "libcrypto",
+        "libcutils",
+        "libdexfile",
+        "libhidl-gen-utils",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "liblzma",
+        "libnativehelper",
+        "libnetworkstacktestsjni",
+        "libpackagelistparser",
+        "libpcre2",
+        "libprocessgroup",
+        "libselinux",
+        "libui",
+        "libutils",
+        "libvintf",
+        "libvndksupport",
+        "libtinyxml2",
+        "libunwindstack",
+        "libutilscallstack",
+        "libziparchive",
+        "libz",
+        "netd_aidl_interface-cpp",
+    ],
+}
+
+cc_library_shared {
+    name: "libnetworkstacktestsjni",
+    srcs: [
+        "jni/**/*.cpp"
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    include_dirs: [
+        "hardware/google/apf",
+    ],
+    shared_libs: [
+        "libbinder",
+        "liblog",
+        "libcutils",
+        "libnativehelper",
+        "netd_aidl_interface-cpp",
+    ],
+    static_libs: [
+        "libapf",
+        "libpcap",
+    ],
+
+}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 8b8474f..9cb2c21 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -15,6 +15,35 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.server.networkstack.tests">
+
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
+    <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
+    <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
+    <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
+    <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
+    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
+    <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
+    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
+    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
+    <uses-permission android:name="android.permission.NETWORK_STACK" />
+
     <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
     </application>
diff --git a/tests/jni/apf_jni.cpp b/tests/jni/apf_jni.cpp
new file mode 100644
index 0000000..4222adf
--- /dev/null
+++ b/tests/jni/apf_jni.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright 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.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <jni.h>
+#include <pcap.h>
+#include <stdlib.h>
+#include <string>
+#include <utils/Log.h>
+#include <vector>
+
+#include "apf_interpreter.h"
+#include "nativehelper/scoped_primitive_array.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+// JNI function acting as simply call-through to native APF interpreter.
+static jint com_android_server_ApfTest_apfSimulate(
+        JNIEnv* env, jclass, jbyteArray jprogram, jbyteArray jpacket,
+        jbyteArray jdata, jint filter_age) {
+
+    ScopedByteArrayRO packet(env, jpacket);
+    uint32_t packet_len = (uint32_t)packet.size();
+    uint32_t program_len = env->GetArrayLength(jprogram);
+    uint32_t data_len = jdata ? env->GetArrayLength(jdata) : 0;
+    std::vector<uint8_t> buf(program_len + data_len, 0);
+
+    env->GetByteArrayRegion(jprogram, 0, program_len, reinterpret_cast<jbyte*>(buf.data()));
+    if (jdata) {
+        // Merge program and data into a single buffer.
+        env->GetByteArrayRegion(jdata, 0, data_len,
+                                reinterpret_cast<jbyte*>(buf.data() + program_len));
+    }
+
+    jint result =
+        accept_packet(buf.data(), program_len, program_len + data_len,
+                        reinterpret_cast<const uint8_t*>(packet.get()), packet_len, filter_age);
+
+    if (jdata) {
+        env->SetByteArrayRegion(jdata, 0, data_len,
+                                reinterpret_cast<jbyte*>(buf.data() + program_len));
+    }
+
+    return result;
+}
+
+class ScopedPcap {
+  public:
+    explicit ScopedPcap(pcap_t* pcap) : pcap_ptr(pcap) {}
+    ~ScopedPcap() {
+        pcap_close(pcap_ptr);
+    }
+
+    pcap_t* get() const { return pcap_ptr; };
+  private:
+    pcap_t* const pcap_ptr;
+};
+
+class ScopedFILE {
+  public:
+    explicit ScopedFILE(FILE* fp) : file(fp) {}
+    ~ScopedFILE() {
+        fclose(file);
+    }
+
+    FILE* get() const { return file; };
+  private:
+    FILE* const file;
+};
+
+static void throwException(JNIEnv* env, const std::string& error) {
+    jclass newExcCls = env->FindClass("java/lang/IllegalStateException");
+    if (newExcCls == 0) {
+      abort();
+      return;
+    }
+    env->ThrowNew(newExcCls, error.c_str());
+}
+
+static jstring com_android_server_ApfTest_compileToBpf(JNIEnv* env, jclass, jstring jfilter) {
+    ScopedUtfChars filter(env, jfilter);
+    std::string bpf_string;
+    ScopedPcap pcap(pcap_open_dead(DLT_EN10MB, 65535));
+    if (pcap.get() == NULL) {
+        throwException(env, "pcap_open_dead failed");
+        return NULL;
+    }
+
+    // Compile "filter" to a BPF program
+    bpf_program bpf;
+    if (pcap_compile(pcap.get(), &bpf, filter.c_str(), 0, PCAP_NETMASK_UNKNOWN)) {
+        throwException(env, "pcap_compile failed");
+        return NULL;
+    }
+
+    // Translate BPF program to human-readable format
+    const struct bpf_insn* insn = bpf.bf_insns;
+    for (uint32_t i = 0; i < bpf.bf_len; i++) {
+        bpf_string += bpf_image(insn++, i);
+        bpf_string += "\n";
+    }
+
+    return env->NewStringUTF(bpf_string.c_str());
+}
+
+static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, jstring jfilter,
+        jstring jpcap_filename, jbyteArray japf_program) {
+    ScopedUtfChars filter(env, jfilter);
+    ScopedUtfChars pcap_filename(env, jpcap_filename);
+    ScopedByteArrayRO apf_program(env, japf_program);
+
+    // Open pcap file for BPF filtering
+    ScopedFILE bpf_fp(fopen(pcap_filename.c_str(), "rb"));
+    char pcap_error[PCAP_ERRBUF_SIZE];
+    ScopedPcap bpf_pcap(pcap_fopen_offline(bpf_fp.get(), pcap_error));
+    if (bpf_pcap.get() == NULL) {
+        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
+        return false;
+    }
+
+    // Open pcap file for APF filtering
+    ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb"));
+    ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error));
+    if (apf_pcap.get() == NULL) {
+        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
+        return false;
+    }
+
+    // Compile "filter" to a BPF program
+    bpf_program bpf;
+    if (pcap_compile(bpf_pcap.get(), &bpf, filter.c_str(), 0, PCAP_NETMASK_UNKNOWN)) {
+        throwException(env, "pcap_compile failed");
+        return false;
+    }
+
+    // Install BPF filter on bpf_pcap
+    if (pcap_setfilter(bpf_pcap.get(), &bpf)) {
+        throwException(env, "pcap_setfilter failed");
+        return false;
+    }
+
+    while (1) {
+        pcap_pkthdr bpf_header, apf_header;
+        // Run BPF filter to the next matching packet.
+        const uint8_t* bpf_packet = pcap_next(bpf_pcap.get(), &bpf_header);
+
+        // Run APF filter to the next matching packet.
+        const uint8_t* apf_packet;
+        do {
+            apf_packet = pcap_next(apf_pcap.get(), &apf_header);
+        } while (apf_packet != NULL && !accept_packet(
+                reinterpret_cast<uint8_t*>(const_cast<int8_t*>(apf_program.get())),
+                apf_program.size(), 0 /* data_len */,
+                apf_packet, apf_header.len, 0 /* filter_age */));
+
+        // Make sure both filters matched the same packet.
+        if (apf_packet == NULL && bpf_packet == NULL)
+            break;
+        if (apf_packet == NULL || bpf_packet == NULL)
+            return false;
+        if (apf_header.len != bpf_header.len ||
+                apf_header.ts.tv_sec != bpf_header.ts.tv_sec ||
+                apf_header.ts.tv_usec != bpf_header.ts.tv_usec ||
+                memcmp(apf_packet, bpf_packet, apf_header.len))
+            return false;
+    }
+    return true;
+}
+
+static jboolean com_android_server_ApfTest_dropsAllPackets(JNIEnv* env, jclass, jbyteArray jprogram,
+        jbyteArray jdata, jstring jpcap_filename) {
+    ScopedUtfChars pcap_filename(env, jpcap_filename);
+    ScopedByteArrayRO apf_program(env, jprogram);
+    uint32_t apf_program_len = (uint32_t)apf_program.size();
+    uint32_t data_len = env->GetArrayLength(jdata);
+    pcap_pkthdr apf_header;
+    const uint8_t* apf_packet;
+    char pcap_error[PCAP_ERRBUF_SIZE];
+    std::vector<uint8_t> buf(apf_program_len + data_len, 0);
+
+    // Merge program and data into a single buffer.
+    env->GetByteArrayRegion(jprogram, 0, apf_program_len, reinterpret_cast<jbyte*>(buf.data()));
+    env->GetByteArrayRegion(jdata, 0, data_len,
+                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
+
+    // Open pcap file
+    ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb"));
+    ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error));
+
+    if (apf_pcap.get() == NULL) {
+        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
+        return false;
+    }
+
+    while ((apf_packet = pcap_next(apf_pcap.get(), &apf_header)) != NULL) {
+        int result = accept_packet(buf.data(), apf_program_len,
+                                    apf_program_len + data_len, apf_packet, apf_header.len, 0);
+
+        // Return false once packet passes the filter
+        if (result) {
+            env->SetByteArrayRegion(jdata, 0, data_len,
+                                    reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
+            return false;
+         }
+    }
+
+    env->SetByteArrayRegion(jdata, 0, data_len,
+                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
+    return true;
+}
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        ALOGE("ERROR: GetEnv failed");
+        return -1;
+    }
+
+    static JNINativeMethod gMethods[] = {
+            { "apfSimulate", "([B[B[BI)I",
+                    (void*)com_android_server_ApfTest_apfSimulate },
+            { "compileToBpf", "(Ljava/lang/String;)Ljava/lang/String;",
+                    (void*)com_android_server_ApfTest_compileToBpf },
+            { "compareBpfApf", "(Ljava/lang/String;Ljava/lang/String;[B)Z",
+                    (void*)com_android_server_ApfTest_compareBpfApf },
+            { "dropsAllPackets", "([B[BLjava/lang/String;)Z",
+                    (void*)com_android_server_ApfTest_dropsAllPackets },
+    };
+
+    jniRegisterNativeMethods(env, "android/net/apf/ApfTest",
+            gMethods, ARRAY_SIZE(gMethods));
+
+    return JNI_VERSION_1_6;
+}
diff --git a/tests/res/raw/apf.pcap b/tests/res/raw/apf.pcap
new file mode 100644
index 0000000..963165f
--- /dev/null
+++ b/tests/res/raw/apf.pcap
Binary files differ
diff --git a/tests/res/raw/apfPcap.pcap b/tests/res/raw/apfPcap.pcap
new file mode 100644
index 0000000..6f69c4a
--- /dev/null
+++ b/tests/res/raw/apfPcap.pcap
Binary files differ
diff --git a/tests/src/android/net/apf/ApfTest.java b/tests/src/android/net/apf/ApfTest.java
new file mode 100644
index 0000000..f76e412
--- /dev/null
+++ b/tests/src/android/net/apf/ApfTest.java
@@ -0,0 +1,1802 @@
+/*
+ * Copyright (C) 2012 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.apf;
+
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.ARPHRD_ETHER;
+import static android.system.OsConstants.ETH_P_ARP;
+import static android.system.OsConstants.ETH_P_IP;
+import static android.system.OsConstants.ETH_P_IPV6;
+import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_STREAM;
+
+import static com.android.internal.util.BitUtils.bytesToBEInt;
+import static com.android.server.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.apf.ApfFilter.ApfConfiguration;
+import android.net.apf.ApfGenerator.IllegalInstructionException;
+import android.net.apf.ApfGenerator.Register;
+import android.net.ip.IIpClientCallbacks;
+import android.net.ip.IpClient;
+import android.net.ip.IpClient.IpClientCallbacksWrapper;
+import android.net.ip.IpClientCallbacks;
+import android.net.metrics.IpConnectivityLog;
+import android.net.metrics.RaEvent;
+import android.net.util.InterfaceParams;
+import android.net.util.SharedLog;
+import android.os.ConditionVariable;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+import com.android.internal.util.HexDump;
+import com.android.server.networkstack.tests.R;
+import com.android.server.util.NetworkStackConstants;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Tests for APF program generator and interpreter.
+ *
+ * Build, install and run with:
+ *  runtest frameworks-net -c android.net.apf.ApfTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ApfTest {
+    private static final int TIMEOUT_MS = 500;
+    private static final int MIN_APF_VERSION = 2;
+
+    @Mock IpConnectivityLog mLog;
+    @Mock Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        // Load up native shared library containing APF interpreter exposed via JNI.
+        System.loadLibrary("networkstacktestsjni");
+    }
+
+    private static final String TAG = "ApfTest";
+    // Expected return codes from APF interpreter.
+    private static final int PASS = 1;
+    private static final int DROP = 0;
+    // Interpreter will just accept packets without link layer headers, so pad fake packet to at
+    // least the minimum packet size.
+    private static final int MIN_PKT_SIZE = 15;
+
+    private static final ApfCapabilities MOCK_APF_CAPABILITIES =
+      new ApfCapabilities(2, 1700, ARPHRD_ETHER);
+
+    private static final boolean DROP_MULTICAST = true;
+    private static final boolean ALLOW_MULTICAST = false;
+
+    private static final boolean DROP_802_3_FRAMES = true;
+    private static final boolean ALLOW_802_3_FRAMES = false;
+
+    // Constants for opcode encoding
+    private static final byte LI_OP   = (byte)(13 << 3);
+    private static final byte LDDW_OP = (byte)(22 << 3);
+    private static final byte STDW_OP = (byte)(23 << 3);
+    private static final byte SIZE0   = (byte)(0 << 1);
+    private static final byte SIZE8   = (byte)(1 << 1);
+    private static final byte SIZE16  = (byte)(2 << 1);
+    private static final byte SIZE32  = (byte)(3 << 1);
+    private static final byte R1 = 1;
+
+    private static ApfConfiguration getDefaultConfig() {
+        ApfFilter.ApfConfiguration config = new ApfConfiguration();
+        config.apfCapabilities = MOCK_APF_CAPABILITIES;
+        config.multicastFilter = ALLOW_MULTICAST;
+        config.ieee802_3Filter = ALLOW_802_3_FRAMES;
+        config.ethTypeBlackList = new int[0];
+        return config;
+    }
+
+    private static String label(int code) {
+        switch (code) {
+            case PASS: return "PASS";
+            case DROP: return "DROP";
+            default:   return "UNKNOWN";
+        }
+    }
+
+    private static void assertReturnCodesEqual(int expected, int got) {
+        assertEquals(label(expected), label(got));
+    }
+
+    private void assertVerdict(int expected, byte[] program, byte[] packet, int filterAge) {
+        assertReturnCodesEqual(expected, apfSimulate(program, packet, null, filterAge));
+    }
+
+    private void assertVerdict(int expected, byte[] program, byte[] packet) {
+        assertReturnCodesEqual(expected, apfSimulate(program, packet, null, 0));
+    }
+
+    private void assertPass(byte[] program, byte[] packet, int filterAge) {
+        assertVerdict(PASS, program, packet, filterAge);
+    }
+
+    private void assertPass(byte[] program, byte[] packet) {
+        assertVerdict(PASS, program, packet);
+    }
+
+    private void assertDrop(byte[] program, byte[] packet, int filterAge) {
+        assertVerdict(DROP, program, packet, filterAge);
+    }
+
+    private void assertDrop(byte[] program, byte[] packet) {
+        assertVerdict(DROP, program, packet);
+    }
+
+    private void assertProgramEquals(byte[] expected, byte[] program) throws AssertionError {
+        // assertArrayEquals() would only print one byte, making debugging difficult.
+        if (!java.util.Arrays.equals(expected, program)) {
+            throw new AssertionError(
+                    "\nexpected: " + HexDump.toHexString(expected) +
+                    "\nactual:   " + HexDump.toHexString(program));
+        }
+    }
+
+    private void assertDataMemoryContents(
+            int expected, byte[] program, byte[] packet, byte[] data, byte[] expected_data)
+            throws IllegalInstructionException, Exception {
+        assertReturnCodesEqual(expected, apfSimulate(program, packet, data, 0 /* filterAge */));
+
+        // assertArrayEquals() would only print one byte, making debugging difficult.
+        if (!java.util.Arrays.equals(expected_data, data)) {
+            throw new Exception(
+                    "\nprogram:     " + HexDump.toHexString(program) +
+                    "\ndata memory: " + HexDump.toHexString(data) +
+                    "\nexpected:    " + HexDump.toHexString(expected_data));
+        }
+    }
+
+    private void assertVerdict(int expected, ApfGenerator gen, byte[] packet, int filterAge)
+            throws IllegalInstructionException {
+        assertReturnCodesEqual(expected, apfSimulate(gen.generate(), packet, null,
+              filterAge));
+    }
+
+    private void assertPass(ApfGenerator gen, byte[] packet, int filterAge)
+            throws IllegalInstructionException {
+        assertVerdict(PASS, gen, packet, filterAge);
+    }
+
+    private void assertDrop(ApfGenerator gen, byte[] packet, int filterAge)
+            throws IllegalInstructionException {
+        assertVerdict(DROP, gen, packet, filterAge);
+    }
+
+    private void assertPass(ApfGenerator gen)
+            throws IllegalInstructionException {
+        assertVerdict(PASS, gen, new byte[MIN_PKT_SIZE], 0);
+    }
+
+    private void assertDrop(ApfGenerator gen)
+            throws IllegalInstructionException {
+        assertVerdict(DROP, gen, new byte[MIN_PKT_SIZE], 0);
+    }
+
+    /**
+     * Test each instruction by generating a program containing the instruction,
+     * generating bytecode for that program and running it through the
+     * interpreter to verify it functions correctly.
+     */
+    @Test
+    public void testApfInstructions() throws IllegalInstructionException {
+        // Empty program should pass because having the program counter reach the
+        // location immediately after the program indicates the packet should be
+        // passed to the AP.
+        ApfGenerator gen = new ApfGenerator(MIN_APF_VERSION);
+        assertPass(gen);
+
+        // Test jumping to pass label.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJump(gen.PASS_LABEL);
+        byte[] program = gen.generate();
+        assertEquals(1, program.length);
+        assertEquals((14 << 3) | (0 << 1) | 0, program[0]);
+        assertPass(program, new byte[MIN_PKT_SIZE], 0);
+
+        // Test jumping to drop label.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJump(gen.DROP_LABEL);
+        program = gen.generate();
+        assertEquals(2, program.length);
+        assertEquals((14 << 3) | (1 << 1) | 0, program[0]);
+        assertEquals(1, program[1]);
+        assertDrop(program, new byte[15], 15);
+
+        // Test jumping if equal to 0.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test jumping if not equal to 0.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL);
+        assertPass(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1);
+        gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test jumping if registers equal.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0EqualsR1(gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test jumping if registers not equal.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL);
+        assertPass(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1);
+        gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test load immediate.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test add.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addAdd(1234567890);
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test subtract.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addAdd(-1234567890);
+        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test or.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addOr(1234567890);
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test and.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addAnd(123456789);
+        gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test left shift.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addLeftShift(1);
+        gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test right shift.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addRightShift(1);
+        gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test multiply.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 123456789);
+        gen.addMul(2);
+        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test divide.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addDiv(2);
+        gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test divide by zero.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addDiv(0);
+        gen.addJump(gen.DROP_LABEL);
+        assertPass(gen);
+
+        // Test add.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 1234567890);
+        gen.addAddR1();
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test subtract.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, -1234567890);
+        gen.addAddR1();
+        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test or.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 1234567890);
+        gen.addOrR1();
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test and.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addLoadImmediate(Register.R1, 123456789);
+        gen.addAndR1();
+        gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test left shift.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addLoadImmediate(Register.R1, 1);
+        gen.addLeftShiftR1();
+        gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test right shift.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addLoadImmediate(Register.R1, -1);
+        gen.addLeftShiftR1();
+        gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test multiply.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 123456789);
+        gen.addLoadImmediate(Register.R1, 2);
+        gen.addMulR1();
+        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test divide.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addLoadImmediate(Register.R1, 2);
+        gen.addDivR1();
+        gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test divide by zero.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addDivR1();
+        gen.addJump(gen.DROP_LABEL);
+        assertPass(gen);
+
+        // Test byte load.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoad8(Register.R0, 1);
+        gen.addJumpIfR0Equals(45, gen.DROP_LABEL);
+        assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
+
+        // Test out of bounds load.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoad8(Register.R0, 16);
+        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
+        assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
+
+        // Test half-word load.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoad16(Register.R0, 1);
+        gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL);
+        assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
+
+        // Test word load.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoad32(Register.R0, 1);
+        gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL);
+        assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0);
+
+        // Test byte indexed load.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 1);
+        gen.addLoad8Indexed(Register.R0, 0);
+        gen.addJumpIfR0Equals(45, gen.DROP_LABEL);
+        assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
+
+        // Test out of bounds indexed load.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 8);
+        gen.addLoad8Indexed(Register.R0, 8);
+        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
+        assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
+
+        // Test half-word indexed load.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 1);
+        gen.addLoad16Indexed(Register.R0, 0);
+        gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL);
+        assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
+
+        // Test word indexed load.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 1);
+        gen.addLoad32Indexed(Register.R0, 0);
+        gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL);
+        assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0);
+
+        // Test jumping if greater than.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL);
+        assertPass(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1);
+        gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test jumping if less than.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0LessThan(0, gen.DROP_LABEL);
+        assertPass(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0LessThan(1, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test jumping if any bits set.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
+        assertPass(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1);
+        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
+        assertDrop(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 3);
+        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test jumping if register greater than.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL);
+        assertPass(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 2);
+        gen.addLoadImmediate(Register.R1, 1);
+        gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test jumping if register less than.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfR0LessThanR1(gen.DROP_LABEL);
+        assertPass(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 1);
+        gen.addJumpIfR0LessThanR1(gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test jumping if any bits set in register.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 3);
+        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
+        assertPass(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 3);
+        gen.addLoadImmediate(Register.R0, 1);
+        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
+        assertDrop(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 3);
+        gen.addLoadImmediate(Register.R0, 3);
+        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test load from memory.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadFromMemory(Register.R0, 0);
+        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test store to memory.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 1234567890);
+        gen.addStoreToMemory(Register.R1, 12);
+        gen.addLoadFromMemory(Register.R0, 12);
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test filter age pre-filled memory.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT);
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen, new byte[MIN_PKT_SIZE], 1234567890);
+
+        // Test packet size pre-filled memory.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
+        gen.addJumpIfR0Equals(MIN_PKT_SIZE, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test IPv4 header size pre-filled memory.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
+        gen.addJumpIfR0Equals(20, gen.DROP_LABEL);
+        assertDrop(gen, new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x45}, 0);
+
+        // Test not.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addNot(Register.R0);
+        gen.addJumpIfR0Equals(~1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test negate.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addNeg(Register.R0);
+        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test move.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 1234567890);
+        gen.addMove(Register.R0);
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addMove(Register.R1);
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test swap.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R1, 1234567890);
+        gen.addSwap();
+        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
+        assertDrop(gen);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1234567890);
+        gen.addSwap();
+        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
+        assertDrop(gen);
+
+        // Test jump if bytes not equal.
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1);
+        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
+        program = gen.generate();
+        assertEquals(6, program.length);
+        assertEquals((13 << 3) | (1 << 1) | 0, program[0]);
+        assertEquals(1, program[1]);
+        assertEquals(((20 << 3) | (1 << 1) | 0) - 256, program[2]);
+        assertEquals(1, program[3]);
+        assertEquals(1, program[4]);
+        assertEquals(123, program[5]);
+        assertDrop(program, new byte[MIN_PKT_SIZE], 0);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1);
+        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
+        byte[] packet123 = {0,123,0,0,0,0,0,0,0,0,0,0,0,0,0};
+        assertPass(gen, packet123, 0);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
+        assertDrop(gen, packet123, 0);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1);
+        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,30,4,5}, gen.DROP_LABEL);
+        byte[] packet12345 = {0,1,2,3,4,5,0,0,0,0,0,0,0,0,0};
+        assertDrop(gen, packet12345, 0);
+        gen = new ApfGenerator(MIN_APF_VERSION);
+        gen.addLoadImmediate(Register.R0, 1);
+        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,3,4,5}, gen.DROP_LABEL);
+        assertPass(gen, packet12345, 0);
+    }
+
+    @Test(expected = ApfGenerator.IllegalInstructionException.class)
+    public void testApfGeneratorWantsV2OrGreater() throws Exception {
+        // The minimum supported APF version is 2.
+        new ApfGenerator(1);
+    }
+
+    @Test
+    public void testApfDataOpcodesWantApfV3() throws IllegalInstructionException, Exception {
+        ApfGenerator gen = new ApfGenerator(MIN_APF_VERSION);
+        try {
+            gen.addStoreData(Register.R0, 0);
+            fail();
+        } catch (IllegalInstructionException expected) {
+            /* pass */
+        }
+        try {
+            gen.addLoadData(Register.R0, 0);
+            fail();
+        } catch (IllegalInstructionException expected) {
+            /* pass */
+        }
+    }
+
+    /**
+     * Test that the generator emits immediates using the shortest possible encoding.
+     */
+    @Test
+    public void testImmediateEncoding() throws IllegalInstructionException {
+        ApfGenerator gen;
+
+        // 0-byte immediate: li R0, 0
+        gen = new ApfGenerator(4);
+        gen.addLoadImmediate(Register.R0, 0);
+        assertProgramEquals(new byte[]{LI_OP | SIZE0}, gen.generate());
+
+        // 1-byte immediate: li R0, 42
+        gen = new ApfGenerator(4);
+        gen.addLoadImmediate(Register.R0, 42);
+        assertProgramEquals(new byte[]{LI_OP | SIZE8, 42}, gen.generate());
+
+        // 2-byte immediate: li R1, 0x1234
+        gen = new ApfGenerator(4);
+        gen.addLoadImmediate(Register.R1, 0x1234);
+        assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, 0x12, 0x34}, gen.generate());
+
+        // 4-byte immediate: li R0, 0x12345678
+        gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R0, 0x12345678);
+        assertProgramEquals(
+                new byte[]{LI_OP | SIZE32, 0x12, 0x34, 0x56, 0x78},
+                gen.generate());
+    }
+
+    /**
+     * Test that the generator emits negative immediates using the shortest possible encoding.
+     */
+    @Test
+    public void testNegativeImmediateEncoding() throws IllegalInstructionException {
+        ApfGenerator gen;
+
+        // 1-byte negative immediate: li R0, -42
+        gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R0, -42);
+        assertProgramEquals(new byte[]{LI_OP | SIZE8, -42}, gen.generate());
+
+        // 2-byte negative immediate: li R1, -0x1122
+        gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R1, -0x1122);
+        assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
+                gen.generate());
+
+        // 4-byte negative immediate: li R0, -0x11223344
+        gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R0, -0x11223344);
+        assertProgramEquals(
+                new byte[]{LI_OP | SIZE32, (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBC},
+                gen.generate());
+    }
+
+    /**
+     * Test that the generator correctly emits positive and negative immediates for LDDW/STDW.
+     */
+    @Test
+    public void testLoadStoreDataEncoding() throws IllegalInstructionException {
+        ApfGenerator gen;
+
+        // Load data with no offset: lddw R0, [0 + r1]
+        gen = new ApfGenerator(3);
+        gen.addLoadData(Register.R0, 0);
+        assertProgramEquals(new byte[]{LDDW_OP | SIZE0}, gen.generate());
+
+        // Store data with 8bit negative offset: lddw r0, [-42 + r1]
+        gen = new ApfGenerator(3);
+        gen.addStoreData(Register.R0, -42);
+        assertProgramEquals(new byte[]{STDW_OP | SIZE8, -42}, gen.generate());
+
+        // Store data to R1 with 16bit negative offset: stdw r1, [-0x1122 + r0]
+        gen = new ApfGenerator(3);
+        gen.addStoreData(Register.R1, -0x1122);
+        assertProgramEquals(new byte[]{STDW_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
+                gen.generate());
+
+        // Load data to R1 with 32bit negative offset: lddw r1, [0xDEADBEEF + r0]
+        gen = new ApfGenerator(3);
+        gen.addLoadData(Register.R1, 0xDEADBEEF);
+        assertProgramEquals(
+                new byte[]{LDDW_OP | SIZE32 | R1, (byte)0xDE, (byte)0xAD, (byte)0xBE, (byte)0xEF},
+                gen.generate());
+    }
+
+    /**
+     * Test that the interpreter correctly executes STDW with a negative 8bit offset
+     */
+    @Test
+    public void testApfDataWrite() throws IllegalInstructionException, Exception {
+        byte[] packet = new byte[MIN_PKT_SIZE];
+        byte[] data = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+        byte[] expected_data = data.clone();
+
+        // No memory access instructions: should leave the data segment untouched.
+        ApfGenerator gen = new ApfGenerator(3);
+        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
+
+        // Expect value 0x87654321 to be stored starting from address -11 from the end of the
+        // data buffer, in big-endian order.
+        gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R0, 0x87654321);
+        gen.addLoadImmediate(Register.R1, -5);
+        gen.addStoreData(Register.R0, -6);  // -5 + -6 = -11 (offset +5 with data_len=16)
+        expected_data[5] = (byte)0x87;
+        expected_data[6] = (byte)0x65;
+        expected_data[7] = (byte)0x43;
+        expected_data[8] = (byte)0x21;
+        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
+    }
+
+    /**
+     * Test that the interpreter correctly executes LDDW with a negative 16bit offset
+     */
+    @Test
+    public void testApfDataRead() throws IllegalInstructionException, Exception {
+        // Program that DROPs if address 10 (-6) contains 0x87654321.
+        ApfGenerator gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R1, 1000);
+        gen.addLoadData(Register.R0, -1006);  // 1000 + -1006 = -6 (offset +10 with data_len=16)
+        gen.addJumpIfR0Equals(0x87654321, gen.DROP_LABEL);
+        byte[] program = gen.generate();
+        byte[] packet = new byte[MIN_PKT_SIZE];
+
+        // Content is incorrect (last byte does not match) -> PASS
+        byte[] data = new byte[16];
+        data[10] = (byte)0x87;
+        data[11] = (byte)0x65;
+        data[12] = (byte)0x43;
+        data[13] = (byte)0x00;  // != 0x21
+        byte[] expected_data = data.clone();
+        assertDataMemoryContents(PASS, program, packet, data, expected_data);
+
+        // Fix the last byte -> conditional jump taken -> DROP
+        data[13] = (byte)0x21;
+        expected_data = data;
+        assertDataMemoryContents(DROP, program, packet, data, expected_data);
+    }
+
+    /**
+     * Test that the interpreter correctly executes LDDW followed by a STDW.
+     * To cover a few more edge cases, LDDW has a 0bit offset, while STDW has a positive 8bit
+     * offset.
+     */
+    @Test
+    public void testApfDataReadModifyWrite() throws IllegalInstructionException, Exception {
+        ApfGenerator gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R1, -22);
+        gen.addLoadData(Register.R0, 0);  // Load from address 32 -22 + 0 = 10
+        gen.addAdd(0x78453412);  // 87654321 + 78453412 = FFAA7733
+        gen.addStoreData(Register.R0, 4);  // Write back to address 32 -22 + 4 = 14
+
+        byte[] packet = new byte[MIN_PKT_SIZE];
+        byte[] data = new byte[32];
+        data[10] = (byte)0x87;
+        data[11] = (byte)0x65;
+        data[12] = (byte)0x43;
+        data[13] = (byte)0x21;
+        byte[] expected_data = data.clone();
+        expected_data[14] = (byte)0xFF;
+        expected_data[15] = (byte)0xAA;
+        expected_data[16] = (byte)0x77;
+        expected_data[17] = (byte)0x33;
+        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
+    }
+
+    @Test
+    public void testApfDataBoundChecking() throws IllegalInstructionException, Exception {
+        byte[] packet = new byte[MIN_PKT_SIZE];
+        byte[] data = new byte[32];
+        byte[] expected_data = data;
+
+        // Program that DROPs unconditionally. This is our the baseline.
+        ApfGenerator gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R0, 3);
+        gen.addLoadData(Register.R1, 7);
+        gen.addJump(gen.DROP_LABEL);
+        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
+
+        // Same program as before, but this time we're trying to load past the end of the data.
+        gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R0, 20);
+        gen.addLoadData(Register.R1, 15);  // 20 + 15 > 32
+        gen.addJump(gen.DROP_LABEL);  // Not reached.
+        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
+
+        // Subtracting an immediate should work...
+        gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R0, 20);
+        gen.addLoadData(Register.R1, -4);
+        gen.addJump(gen.DROP_LABEL);
+        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
+
+        // ...and underflowing simply wraps around to the end of the buffer...
+        gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R0, 20);
+        gen.addLoadData(Register.R1, -30);
+        gen.addJump(gen.DROP_LABEL);
+        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
+
+        // ...but doesn't allow accesses before the start of the buffer
+        gen = new ApfGenerator(3);
+        gen.addLoadImmediate(Register.R0, 20);
+        gen.addLoadData(Register.R1, -1000);
+        gen.addJump(gen.DROP_LABEL);  // Not reached.
+        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
+    }
+
+    /**
+     * Generate some BPF programs, translate them to APF, then run APF and BPF programs
+     * over packet traces and verify both programs filter out the same packets.
+     */
+    @Test
+    public void testApfAgainstBpf() throws Exception {
+        String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
+                "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
+                "arp or icmp6 or portrange 53-54", "portrange 53-54 or portrange 100-50000",
+                "tcp[tcpflags] & (tcp-ack|tcp-fin) != 0 and (ip[2:2] > 57 or icmp)" };
+        String pcap_filename = stageFile(R.raw.apf);
+        for (String tcpdump_filter : tcpdump_filters) {
+            byte[] apf_program = Bpf2Apf.convert(compileToBpf(tcpdump_filter));
+            assertTrue("Failed to match for filter: " + tcpdump_filter,
+                    compareBpfApf(tcpdump_filter, pcap_filename, apf_program));
+        }
+    }
+
+    /**
+     * Generate APF program, run pcap file though APF filter, then check all the packets in the file
+     * should be dropped.
+     */
+    @Test
+    public void testApfFilterPcapFile() throws Exception {
+        final byte[] MOCK_PCAP_IPV4_ADDR = {(byte) 172, 16, 7, (byte) 151};
+        String pcapFilename = stageFile(R.raw.apfPcap);
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_PCAP_IPV4_ADDR), 16);
+        LinkProperties lp = new LinkProperties();
+        lp.addLinkAddress(link);
+
+        ApfConfiguration config = getDefaultConfig();
+        ApfCapabilities MOCK_APF_PCAP_CAPABILITIES = new ApfCapabilities(4, 1700, ARPHRD_ETHER);
+        config.apfCapabilities = MOCK_APF_PCAP_CAPABILITIES;
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
+        apfFilter.setLinkProperties(lp);
+        byte[] program = ipClientCallback.getApfProgram();
+        byte[] data = new byte[ApfFilter.Counter.totalSize()];
+        final boolean result;
+
+        result = dropsAllPackets(program, data, pcapFilename);
+        Log.i(TAG, "testApfFilterPcapFile(): Data counters: " + HexDump.toHexString(data, false));
+
+        assertTrue("Failed to drop all packets by filter. \nAPF counters:" +
+            HexDump.toHexString(data, false), result);
+    }
+
+    private class MockIpClientCallback extends IpClientCallbacksWrapper {
+        private final ConditionVariable mGotApfProgram = new ConditionVariable();
+        private byte[] mLastApfProgram;
+
+        MockIpClientCallback() {
+            super(mock(IIpClientCallbacks.class), mock(SharedLog.class));
+        }
+
+        @Override
+        public void installPacketFilter(byte[] filter) {
+            mLastApfProgram = filter;
+            mGotApfProgram.open();
+        }
+
+        public void resetApfProgramWait() {
+            mGotApfProgram.close();
+        }
+
+        public byte[] getApfProgram() {
+            assertTrue(mGotApfProgram.block(TIMEOUT_MS));
+            return mLastApfProgram;
+        }
+
+        public void assertNoProgramUpdate() {
+            assertFalse(mGotApfProgram.block(TIMEOUT_MS));
+        }
+    }
+
+    private static class TestApfFilter extends ApfFilter {
+        public static final byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6};
+
+        private FileDescriptor mWriteSocket;
+        private final long mFixedTimeMs = SystemClock.elapsedRealtime();
+
+        public TestApfFilter(Context context, ApfConfiguration config,
+                IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) throws Exception {
+            super(context, config, InterfaceParams.getByName("lo"), ipClientCallback, log);
+        }
+
+        // Pretend an RA packet has been received and show it to ApfFilter.
+        public void pretendPacketReceived(byte[] packet) throws IOException, ErrnoException {
+            // ApfFilter's ReceiveThread will be waiting to read this.
+            Os.write(mWriteSocket, packet, 0, packet.length);
+        }
+
+        @Override
+        protected long currentTimeSeconds() {
+            return mFixedTimeMs / DateUtils.SECOND_IN_MILLIS;
+        }
+
+        @Override
+        void maybeStartFilter() {
+            mHardwareAddress = MOCK_MAC_ADDR;
+            installNewProgramLocked();
+
+            // Create two sockets, "readSocket" and "mWriteSocket" and connect them together.
+            FileDescriptor readSocket = new FileDescriptor();
+            mWriteSocket = new FileDescriptor();
+            try {
+                Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mWriteSocket, readSocket);
+            } catch (ErrnoException e) {
+                fail();
+                return;
+            }
+            // Now pass readSocket to ReceiveThread as if it was setup to read raw RAs.
+            // This allows us to pretend RA packets have been recieved via pretendPacketReceived().
+            mReceiveThread = new ReceiveThread(readSocket);
+            mReceiveThread.start();
+        }
+
+        @Override
+        public void shutdown() {
+            super.shutdown();
+            IoUtils.closeQuietly(mWriteSocket);
+        }
+    }
+
+    private static final int ETH_HEADER_LEN = 14;
+    private static final int ETH_DEST_ADDR_OFFSET = 0;
+    private static final int ETH_ETHERTYPE_OFFSET = 12;
+    private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
+            {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+    private static final int IPV4_VERSION_IHL_OFFSET = ETH_HEADER_LEN + 0;
+    private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
+    private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
+    private static final byte[] IPV4_BROADCAST_ADDRESS =
+            {(byte) 255, (byte) 255, (byte) 255, (byte) 255};
+
+    private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6;
+    private static final int IPV6_HEADER_LEN = 40;
+    private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24;
+    // The IPv6 all nodes address ff02::1
+    private static final byte[] IPV6_ALL_NODES_ADDRESS =
+            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+    private static final byte[] IPV6_ALL_ROUTERS_ADDRESS =
+            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
+
+    private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
+    private static final int ICMP6_ROUTER_SOLICITATION = 133;
+    private static final int ICMP6_ROUTER_ADVERTISEMENT = 134;
+    private static final int ICMP6_NEIGHBOR_SOLICITATION = 135;
+    private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136;
+
+    private static final int ICMP6_RA_HEADER_LEN = 16;
+    private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
+            ETH_HEADER_LEN + IPV6_HEADER_LEN + 6;
+    private static final int ICMP6_RA_CHECKSUM_OFFSET =
+            ETH_HEADER_LEN + IPV6_HEADER_LEN + 2;
+    private static final int ICMP6_RA_OPTION_OFFSET =
+            ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
+
+    private static final int ICMP6_PREFIX_OPTION_TYPE = 3;
+    private static final int ICMP6_PREFIX_OPTION_LEN = 32;
+    private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET = 4;
+    private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8;
+
+    // From RFC6106: Recursive DNS Server option
+    private static final int ICMP6_RDNSS_OPTION_TYPE = 25;
+    // From RFC6106: DNS Search List option
+    private static final int ICMP6_DNSSL_OPTION_TYPE = 31;
+
+    // From RFC4191: Route Information option
+    private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24;
+    // Above three options all have the same format:
+    private static final int ICMP6_4_BYTE_OPTION_LEN = 8;
+    private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4;
+    private static final int ICMP6_4_BYTE_LIFETIME_LEN = 4;
+
+    private static final int UDP_HEADER_LEN = 8;
+    private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 22;
+
+    private static final int DHCP_CLIENT_PORT = 68;
+    private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 48;
+
+    private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN;
+    private static final byte[] ARP_IPV4_REQUEST_HEADER = {
+            0, 1, // Hardware type: Ethernet (1)
+            8, 0, // Protocol type: IP (0x0800)
+            6,    // Hardware size: 6
+            4,    // Protocol size: 4
+            0, 1  // Opcode: request (1)
+    };
+    private static final byte[] ARP_IPV4_REPLY_HEADER = {
+            0, 1, // Hardware type: Ethernet (1)
+            8, 0, // Protocol type: IP (0x0800)
+            6,    // Hardware size: 6
+            4,    // Protocol size: 4
+            0, 2  // Opcode: reply (2)
+    };
+    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
+    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
+
+    private static final byte[] MOCK_IPV4_ADDR           = {10, 0, 0, 1};
+    private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19
+    private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1};
+    private static final byte[] ANOTHER_IPV4_ADDR        = {10, 0, 0, 2};
+    private static final byte[] IPV4_SOURCE_ADDR         = {10, 0, 0, 3};
+    private static final byte[] ANOTHER_IPV4_SOURCE_ADDR = {(byte) 192, 0, 2, 1};
+    private static final byte[] BUG_PROBE_SOURCE_ADDR1   = {0, 0, 1, 2};
+    private static final byte[] BUG_PROBE_SOURCE_ADDR2   = {3, 4, 0, 0};
+    private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
+
+    // Helper to initialize a default apfFilter.
+    private ApfFilter setupApfFilter(
+            IpClientCallbacksWrapper ipClientCallback, ApfConfiguration config) throws Exception {
+        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
+        LinkProperties lp = new LinkProperties();
+        lp.addLinkAddress(link);
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
+        apfFilter.setLinkProperties(lp);
+        return apfFilter;
+    }
+
+    @Test
+    public void testApfFilterIPv4() throws Exception {
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
+        LinkProperties lp = new LinkProperties();
+        lp.addLinkAddress(link);
+
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
+        apfFilter.setLinkProperties(lp);
+
+        byte[] program = ipClientCallback.getApfProgram();
+
+        // Verify empty packet of 100 zero bytes is passed
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        assertPass(program, packet.array());
+
+        // Verify unicast IPv4 packet is passed
+        put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_IPV4_ADDR);
+        assertPass(program, packet.array());
+
+        // Verify L2 unicast to IPv4 broadcast addresses is dropped (b/30231088)
+        put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
+        assertDrop(program, packet.array());
+        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR);
+        assertDrop(program, packet.array());
+
+        // Verify multicast/broadcast IPv4, not DHCP to us, is dropped
+        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
+        assertDrop(program, packet.array());
+        packet.put(IPV4_VERSION_IHL_OFFSET, (byte)0x45);
+        assertDrop(program, packet.array());
+        packet.put(IPV4_PROTOCOL_OFFSET, (byte)IPPROTO_UDP);
+        assertDrop(program, packet.array());
+        packet.putShort(UDP_DESTINATION_PORT_OFFSET, (short)DHCP_CLIENT_PORT);
+        assertDrop(program, packet.array());
+        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_MULTICAST_IPV4_ADDR);
+        assertDrop(program, packet.array());
+        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR);
+        assertDrop(program, packet.array());
+        put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
+        assertDrop(program, packet.array());
+
+        // Verify broadcast IPv4 DHCP to us is passed
+        put(packet, DHCP_CLIENT_MAC_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
+        assertPass(program, packet.array());
+
+        // Verify unicast IPv4 DHCP to us is passed
+        put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
+        assertPass(program, packet.array());
+
+        apfFilter.shutdown();
+    }
+
+    @Test
+    public void testApfFilterIPv6() throws Exception {
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        ApfConfiguration config = getDefaultConfig();
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
+        byte[] program = ipClientCallback.getApfProgram();
+
+        // Verify empty IPv6 packet is passed
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        assertPass(program, packet.array());
+
+        // Verify empty ICMPv6 packet is passed
+        packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
+        assertPass(program, packet.array());
+
+        // Verify empty ICMPv6 NA packet is passed
+        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_NEIGHBOR_ANNOUNCEMENT);
+        assertPass(program, packet.array());
+
+        // Verify ICMPv6 NA to ff02::1 is dropped
+        put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_NODES_ADDRESS);
+        assertDrop(program, packet.array());
+
+        // Verify ICMPv6 RS to any is dropped
+        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_SOLICITATION);
+        assertDrop(program, packet.array());
+        put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_ROUTERS_ADDRESS);
+        assertDrop(program, packet.array());
+
+        apfFilter.shutdown();
+    }
+
+    @Test
+    public void testApfFilterMulticast() throws Exception {
+        final byte[] unicastIpv4Addr   = {(byte)192,0,2,63};
+        final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
+        final byte[] multicastIpv4Addr = {(byte)224,0,0,1};
+        final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb};
+
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        LinkAddress link = new LinkAddress(InetAddress.getByAddress(unicastIpv4Addr), 24);
+        LinkProperties lp = new LinkProperties();
+        lp.addLinkAddress(link);
+
+        ApfConfiguration config = getDefaultConfig();
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
+        apfFilter.setLinkProperties(lp);
+
+        byte[] program = ipClientCallback.getApfProgram();
+
+        // Construct IPv4 and IPv6 multicast packets.
+        ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]);
+        mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        put(mcastv4packet, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr);
+
+        ByteBuffer mcastv6packet = ByteBuffer.wrap(new byte[100]);
+        mcastv6packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_UDP);
+        put(mcastv6packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr);
+
+        // Construct IPv4 broadcast packet.
+        ByteBuffer bcastv4packet1 = ByteBuffer.wrap(new byte[100]);
+        bcastv4packet1.put(ETH_BROADCAST_MAC_ADDRESS);
+        bcastv4packet1.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        put(bcastv4packet1, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr);
+
+        ByteBuffer bcastv4packet2 = ByteBuffer.wrap(new byte[100]);
+        bcastv4packet2.put(ETH_BROADCAST_MAC_ADDRESS);
+        bcastv4packet2.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        put(bcastv4packet2, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
+
+        // Construct IPv4 broadcast with L2 unicast address packet (b/30231088).
+        ByteBuffer bcastv4unicastl2packet = ByteBuffer.wrap(new byte[100]);
+        bcastv4unicastl2packet.put(TestApfFilter.MOCK_MAC_ADDR);
+        bcastv4unicastl2packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        put(bcastv4unicastl2packet, IPV4_DEST_ADDR_OFFSET, broadcastIpv4Addr);
+
+        // Verify initially disabled multicast filter is off
+        assertPass(program, mcastv4packet.array());
+        assertPass(program, mcastv6packet.array());
+        assertPass(program, bcastv4packet1.array());
+        assertPass(program, bcastv4packet2.array());
+        assertPass(program, bcastv4unicastl2packet.array());
+
+        // Turn on multicast filter and verify it works
+        ipClientCallback.resetApfProgramWait();
+        apfFilter.setMulticastFilter(true);
+        program = ipClientCallback.getApfProgram();
+        assertDrop(program, mcastv4packet.array());
+        assertDrop(program, mcastv6packet.array());
+        assertDrop(program, bcastv4packet1.array());
+        assertDrop(program, bcastv4packet2.array());
+        assertDrop(program, bcastv4unicastl2packet.array());
+
+        // Turn off multicast filter and verify it's off
+        ipClientCallback.resetApfProgramWait();
+        apfFilter.setMulticastFilter(false);
+        program = ipClientCallback.getApfProgram();
+        assertPass(program, mcastv4packet.array());
+        assertPass(program, mcastv6packet.array());
+        assertPass(program, bcastv4packet1.array());
+        assertPass(program, bcastv4packet2.array());
+        assertPass(program, bcastv4unicastl2packet.array());
+
+        // Verify it can be initialized to on
+        ipClientCallback.resetApfProgramWait();
+        apfFilter.shutdown();
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
+        apfFilter.setLinkProperties(lp);
+        program = ipClientCallback.getApfProgram();
+        assertDrop(program, mcastv4packet.array());
+        assertDrop(program, mcastv6packet.array());
+        assertDrop(program, bcastv4packet1.array());
+        assertDrop(program, bcastv4unicastl2packet.array());
+
+        // Verify that ICMPv6 multicast is not dropped.
+        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
+        assertPass(program, mcastv6packet.array());
+
+        apfFilter.shutdown();
+    }
+
+    @Test
+    public void testApfFilterMulticastPingWhileDozing() throws Exception {
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        ApfFilter apfFilter = setupApfFilter(ipClientCallback, getDefaultConfig());
+
+        // Construct a multicast ICMPv6 ECHO request.
+        final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb};
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
+        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMPV6_ECHO_REQUEST_TYPE);
+        put(packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr);
+
+        // Normally, we let multicast pings alone...
+        assertPass(ipClientCallback.getApfProgram(), packet.array());
+
+        // ...and even while dozing...
+        apfFilter.setDozeMode(true);
+        assertPass(ipClientCallback.getApfProgram(), packet.array());
+
+        // ...but when the multicast filter is also enabled, drop the multicast pings to save power.
+        apfFilter.setMulticastFilter(true);
+        assertDrop(ipClientCallback.getApfProgram(), packet.array());
+
+        // However, we should still let through all other ICMPv6 types.
+        ByteBuffer raPacket = ByteBuffer.wrap(packet.array().clone());
+        raPacket.put(ICMP6_TYPE_OFFSET, (byte) NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT);
+        assertPass(ipClientCallback.getApfProgram(), raPacket.array());
+
+        // Now wake up from doze mode to ensure that we no longer drop the packets.
+        // (The multicast filter is still enabled at this point).
+        apfFilter.setDozeMode(false);
+        assertPass(ipClientCallback.getApfProgram(), packet.array());
+
+        apfFilter.shutdown();
+    }
+
+    @Test
+    public void testApfFilter802_3() throws Exception {
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        ApfConfiguration config = getDefaultConfig();
+        ApfFilter apfFilter = setupApfFilter(ipClientCallback, config);
+        byte[] program = ipClientCallback.getApfProgram();
+
+        // Verify empty packet of 100 zero bytes is passed
+        // Note that eth-type = 0 makes it an IEEE802.3 frame
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        assertPass(program, packet.array());
+
+        // Verify empty packet with IPv4 is passed
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        assertPass(program, packet.array());
+
+        // Verify empty IPv6 packet is passed
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        assertPass(program, packet.array());
+
+        // Now turn on the filter
+        ipClientCallback.resetApfProgramWait();
+        apfFilter.shutdown();
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        apfFilter = setupApfFilter(ipClientCallback, config);
+        program = ipClientCallback.getApfProgram();
+
+        // Verify that IEEE802.3 frame is dropped
+        // In this case ethtype is used for payload length
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)(100 - 14));
+        assertDrop(program, packet.array());
+
+        // Verify that IPv4 (as example of Ethernet II) frame will pass
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        assertPass(program, packet.array());
+
+        // Verify that IPv6 (as example of Ethernet II) frame will pass
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        assertPass(program, packet.array());
+
+        apfFilter.shutdown();
+    }
+
+    @Test
+    public void testApfFilterEthTypeBL() throws Exception {
+        final int[] emptyBlackList = {};
+        final int[] ipv4BlackList = {ETH_P_IP};
+        final int[] ipv4Ipv6BlackList = {ETH_P_IP, ETH_P_IPV6};
+
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        ApfConfiguration config = getDefaultConfig();
+        ApfFilter apfFilter = setupApfFilter(ipClientCallback, config);
+        byte[] program = ipClientCallback.getApfProgram();
+
+        // Verify empty packet of 100 zero bytes is passed
+        // Note that eth-type = 0 makes it an IEEE802.3 frame
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        assertPass(program, packet.array());
+
+        // Verify empty packet with IPv4 is passed
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        assertPass(program, packet.array());
+
+        // Verify empty IPv6 packet is passed
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        assertPass(program, packet.array());
+
+        // Now add IPv4 to the black list
+        ipClientCallback.resetApfProgramWait();
+        apfFilter.shutdown();
+        config.ethTypeBlackList = ipv4BlackList;
+        apfFilter = setupApfFilter(ipClientCallback, config);
+        program = ipClientCallback.getApfProgram();
+
+        // Verify that IPv4 frame will be dropped
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        assertDrop(program, packet.array());
+
+        // Verify that IPv6 frame will pass
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        assertPass(program, packet.array());
+
+        // Now let us have both IPv4 and IPv6 in the black list
+        ipClientCallback.resetApfProgramWait();
+        apfFilter.shutdown();
+        config.ethTypeBlackList = ipv4Ipv6BlackList;
+        apfFilter = setupApfFilter(ipClientCallback, config);
+        program = ipClientCallback.getApfProgram();
+
+        // Verify that IPv4 frame will be dropped
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
+        assertDrop(program, packet.array());
+
+        // Verify that IPv6 frame will be dropped
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        assertDrop(program, packet.array());
+
+        apfFilter.shutdown();
+    }
+
+    private byte[] getProgram(MockIpClientCallback cb, ApfFilter filter, LinkProperties lp) {
+        cb.resetApfProgramWait();
+        filter.setLinkProperties(lp);
+        return cb.getApfProgram();
+    }
+
+    private void verifyArpFilter(byte[] program, int filterResult) {
+        // Verify ARP request packet
+        assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR));
+        assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR));
+        assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR));
+
+        // Verify ARP reply packets from different source ip
+        assertDrop(program, arpReply(IPV4_ANY_HOST_ADDR, IPV4_ANY_HOST_ADDR));
+        assertPass(program, arpReply(ANOTHER_IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
+        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR1, IPV4_ANY_HOST_ADDR));
+        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR2, IPV4_ANY_HOST_ADDR));
+
+        // Verify unicast ARP reply packet is always accepted.
+        assertPass(program, arpReply(IPV4_SOURCE_ADDR, MOCK_IPV4_ADDR));
+        assertPass(program, arpReply(IPV4_SOURCE_ADDR, ANOTHER_IPV4_ADDR));
+        assertPass(program, arpReply(IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
+
+        // Verify GARP reply packets are always filtered
+        assertDrop(program, garpReply());
+    }
+
+    @Test
+    public void testApfFilterArp() throws Exception {
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
+
+        // Verify initially ARP request filter is off, and GARP filter is on.
+        verifyArpFilter(ipClientCallback.getApfProgram(), PASS);
+
+        // Inform ApfFilter of our address and verify ARP filtering is on
+        LinkAddress linkAddress = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 24);
+        LinkProperties lp = new LinkProperties();
+        assertTrue(lp.addLinkAddress(linkAddress));
+        verifyArpFilter(getProgram(ipClientCallback, apfFilter, lp), DROP);
+
+        // Inform ApfFilter of loss of IP and verify ARP filtering is off
+        verifyArpFilter(getProgram(ipClientCallback, apfFilter, new LinkProperties()), PASS);
+
+        apfFilter.shutdown();
+    }
+
+    private static byte[] arpReply(byte[] sip, byte[] tip) {
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
+        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
+        put(packet, ARP_SOURCE_IP_ADDRESS_OFFSET, sip);
+        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
+        return packet.array();
+    }
+
+    private static byte[] arpRequestBroadcast(byte[] tip) {
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
+        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
+        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REQUEST_HEADER);
+        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
+        return packet.array();
+    }
+
+    private static byte[] garpReply() {
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
+        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
+        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
+        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, IPV4_ANY_HOST_ADDR);
+        return packet.array();
+    }
+
+    // Verify that the last program pushed to the IpClient.Callback properly filters the
+    // given packet for the given lifetime.
+    private void verifyRaLifetime(byte[] program, ByteBuffer packet, int lifetime) {
+        final int FRACTION_OF_LIFETIME = 6;
+        final int ageLimit = lifetime / FRACTION_OF_LIFETIME;
+
+        // Verify new program should drop RA for 1/6th its lifetime and pass afterwards.
+        assertDrop(program, packet.array());
+        assertDrop(program, packet.array(), ageLimit);
+        assertPass(program, packet.array(), ageLimit + 1);
+        assertPass(program, packet.array(), lifetime);
+        // Verify RA checksum is ignored
+        final short originalChecksum = packet.getShort(ICMP6_RA_CHECKSUM_OFFSET);
+        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)12345);
+        assertDrop(program, packet.array());
+        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)-12345);
+        assertDrop(program, packet.array());
+        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, originalChecksum);
+
+        // Verify other changes to RA make it not match filter
+        final byte originalFirstByte = packet.get(0);
+        packet.put(0, (byte)-1);
+        assertPass(program, packet.array());
+        packet.put(0, (byte)0);
+        assertDrop(program, packet.array());
+        packet.put(0, originalFirstByte);
+    }
+
+    // Test that when ApfFilter is shown the given packet, it generates a program to filter it
+    // for the given lifetime.
+    private void verifyRaLifetime(TestApfFilter apfFilter, MockIpClientCallback ipClientCallback,
+            ByteBuffer packet, int lifetime) throws IOException, ErrnoException {
+        // Verify new program generated if ApfFilter witnesses RA
+        ipClientCallback.resetApfProgramWait();
+        apfFilter.pretendPacketReceived(packet.array());
+        byte[] program = ipClientCallback.getApfProgram();
+        verifyRaLifetime(program, packet, lifetime);
+    }
+
+    private void verifyRaEvent(RaEvent expected) {
+        ArgumentCaptor<IpConnectivityLog.Event> captor =
+                ArgumentCaptor.forClass(IpConnectivityLog.Event.class);
+        verify(mLog, atLeastOnce()).log(captor.capture());
+        RaEvent got = lastRaEvent(captor.getAllValues());
+        if (!raEventEquals(expected, got)) {
+            assertEquals(expected, got);  // fail for printing an assertion error message.
+        }
+    }
+
+    private RaEvent lastRaEvent(List<IpConnectivityLog.Event> events) {
+        RaEvent got = null;
+        for (Parcelable ev : events) {
+            if (ev instanceof RaEvent) {
+                got = (RaEvent) ev;
+            }
+        }
+        return got;
+    }
+
+    private boolean raEventEquals(RaEvent ev1, RaEvent ev2) {
+        return (ev1 != null) && (ev2 != null)
+                && (ev1.routerLifetime == ev2.routerLifetime)
+                && (ev1.prefixValidLifetime == ev2.prefixValidLifetime)
+                && (ev1.prefixPreferredLifetime == ev2.prefixPreferredLifetime)
+                && (ev1.routeInfoLifetime == ev2.routeInfoLifetime)
+                && (ev1.rdnssLifetime == ev2.rdnssLifetime)
+                && (ev1.dnsslLifetime == ev2.dnsslLifetime);
+    }
+
+    private void assertInvalidRa(TestApfFilter apfFilter, MockIpClientCallback ipClientCallback,
+            ByteBuffer packet) throws IOException, ErrnoException {
+        ipClientCallback.resetApfProgramWait();
+        apfFilter.pretendPacketReceived(packet.array());
+        ipClientCallback.assertNoProgramUpdate();
+    }
+
+    @Test
+    public void testApfFilterRa() throws Exception {
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
+        byte[] program = ipClientCallback.getApfProgram();
+
+        final int ROUTER_LIFETIME = 1000;
+        final int PREFIX_VALID_LIFETIME = 200;
+        final int PREFIX_PREFERRED_LIFETIME = 100;
+        final int RDNSS_LIFETIME  = 300;
+        final int ROUTE_LIFETIME  = 400;
+        // Note that lifetime of 2000 will be ignored in favor of shorter route lifetime of 1000.
+        final int DNSSL_LIFETIME  = 2000;
+        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET = ETH_HEADER_LEN;
+        // IPv6, traffic class = 0, flow label = 0x12345
+        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL = 0x60012345;
+
+        // Verify RA is passed the first time
+        ByteBuffer basePacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
+        basePacket.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
+        basePacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
+                VERSION_TRAFFIC_CLASS_FLOW_LABEL);
+        basePacket.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
+        basePacket.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_ADVERTISEMENT);
+        basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)ROUTER_LIFETIME);
+        basePacket.position(IPV6_DEST_ADDR_OFFSET);
+        basePacket.put(IPV6_ALL_NODES_ADDRESS);
+        assertPass(program, basePacket.array());
+
+        verifyRaLifetime(apfFilter, ipClientCallback, basePacket, ROUTER_LIFETIME);
+        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, -1));
+
+        ByteBuffer newFlowLabelPacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
+        basePacket.clear();
+        newFlowLabelPacket.put(basePacket);
+        // Check that changes are ignored in every byte of the flow label.
+        newFlowLabelPacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
+                VERSION_TRAFFIC_CLASS_FLOW_LABEL + 0x11111);
+
+        // Ensure zero-length options cause the packet to be silently skipped.
+        // Do this before we test other packets. http://b/29586253
+        ByteBuffer zeroLengthOptionPacket = ByteBuffer.wrap(
+                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
+        basePacket.clear();
+        zeroLengthOptionPacket.put(basePacket);
+        zeroLengthOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
+        zeroLengthOptionPacket.put((byte)0);
+        assertInvalidRa(apfFilter, ipClientCallback, zeroLengthOptionPacket);
+
+        // Generate several RAs with different options and lifetimes, and verify when
+        // ApfFilter is shown these packets, it generates programs to filter them for the
+        // appropriate lifetime.
+        ByteBuffer prefixOptionPacket = ByteBuffer.wrap(
+                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_LEN]);
+        basePacket.clear();
+        prefixOptionPacket.put(basePacket);
+        prefixOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
+        prefixOptionPacket.put((byte)(ICMP6_PREFIX_OPTION_LEN / 8));
+        prefixOptionPacket.putInt(
+                ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
+                PREFIX_PREFERRED_LIFETIME);
+        prefixOptionPacket.putInt(
+                ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
+                PREFIX_VALID_LIFETIME);
+        verifyRaLifetime(
+                apfFilter, ipClientCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
+        verifyRaEvent(new RaEvent(
+                ROUTER_LIFETIME, PREFIX_VALID_LIFETIME, PREFIX_PREFERRED_LIFETIME, -1, -1, -1));
+
+        ByteBuffer rdnssOptionPacket = ByteBuffer.wrap(
+                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
+        basePacket.clear();
+        rdnssOptionPacket.put(basePacket);
+        rdnssOptionPacket.put((byte)ICMP6_RDNSS_OPTION_TYPE);
+        rdnssOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
+        rdnssOptionPacket.putInt(
+                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, RDNSS_LIFETIME);
+        verifyRaLifetime(apfFilter, ipClientCallback, rdnssOptionPacket, RDNSS_LIFETIME);
+        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, RDNSS_LIFETIME, -1));
+
+        ByteBuffer routeInfoOptionPacket = ByteBuffer.wrap(
+                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
+        basePacket.clear();
+        routeInfoOptionPacket.put(basePacket);
+        routeInfoOptionPacket.put((byte)ICMP6_ROUTE_INFO_OPTION_TYPE);
+        routeInfoOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
+        routeInfoOptionPacket.putInt(
+                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, ROUTE_LIFETIME);
+        verifyRaLifetime(apfFilter, ipClientCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
+        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, ROUTE_LIFETIME, -1, -1));
+
+        ByteBuffer dnsslOptionPacket = ByteBuffer.wrap(
+                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
+        basePacket.clear();
+        dnsslOptionPacket.put(basePacket);
+        dnsslOptionPacket.put((byte)ICMP6_DNSSL_OPTION_TYPE);
+        dnsslOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
+        dnsslOptionPacket.putInt(
+                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, DNSSL_LIFETIME);
+        verifyRaLifetime(apfFilter, ipClientCallback, dnsslOptionPacket, ROUTER_LIFETIME);
+        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, DNSSL_LIFETIME));
+
+        // Verify that current program filters all five RAs:
+        program = ipClientCallback.getApfProgram();
+        verifyRaLifetime(program, basePacket, ROUTER_LIFETIME);
+        verifyRaLifetime(program, newFlowLabelPacket, ROUTER_LIFETIME);
+        verifyRaLifetime(program, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
+        verifyRaLifetime(program, rdnssOptionPacket, RDNSS_LIFETIME);
+        verifyRaLifetime(program, routeInfoOptionPacket, ROUTE_LIFETIME);
+        verifyRaLifetime(program, dnsslOptionPacket, ROUTER_LIFETIME);
+
+        apfFilter.shutdown();
+    }
+
+    /**
+     * Stage a file for testing, i.e. make it native accessible. Given a resource ID,
+     * copy that resource into the app's data directory and return the path to it.
+     */
+    private String stageFile(int rawId) throws Exception {
+        File file = new File(InstrumentationRegistry.getContext().getFilesDir(), "staged_file");
+        new File(file.getParent()).mkdirs();
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
+            out = new FileOutputStream(file);
+            Streams.copy(in, out);
+        } finally {
+            if (in != null) in.close();
+            if (out != null) out.close();
+        }
+        return file.getAbsolutePath();
+    }
+
+    private static void put(ByteBuffer buffer, int position, byte[] bytes) {
+        final int original = buffer.position();
+        buffer.position(position);
+        buffer.put(bytes);
+        buffer.position(original);
+    }
+
+    @Test
+    public void testRaParsing() throws Exception {
+        final int maxRandomPacketSize = 512;
+        final Random r = new Random();
+        MockIpClientCallback cb = new MockIpClientCallback();
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
+        for (int i = 0; i < 1000; i++) {
+            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
+            r.nextBytes(packet);
+            try {
+                apfFilter.new Ra(packet, packet.length);
+            } catch (ApfFilter.InvalidRaException e) {
+            } catch (Exception e) {
+                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
+            }
+        }
+    }
+
+    @Test
+    public void testRaProcessing() throws Exception {
+        final int maxRandomPacketSize = 512;
+        final Random r = new Random();
+        MockIpClientCallback cb = new MockIpClientCallback();
+        ApfConfiguration config = getDefaultConfig();
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
+        for (int i = 0; i < 1000; i++) {
+            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
+            r.nextBytes(packet);
+            try {
+                apfFilter.processRa(packet, packet.length);
+            } catch (Exception e) {
+                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
+            }
+        }
+    }
+
+    /**
+     * Call the APF interpreter to run {@code program} on {@code packet} with persistent memory
+     * segment {@data} pretending the filter was installed {@code filter_age} seconds ago.
+     */
+    private native static int apfSimulate(byte[] program, byte[] packet, byte[] data,
+        int filter_age);
+
+    /**
+     * Compile a tcpdump human-readable filter (e.g. "icmp" or "tcp port 54") into a BPF
+     * prorgam and return a human-readable dump of the BPF program identical to "tcpdump -d".
+     */
+    private native static String compileToBpf(String filter);
+
+    /**
+     * Open packet capture file {@code pcap_filename} and filter the packets using tcpdump
+     * human-readable filter (e.g. "icmp" or "tcp port 54") compiled to a BPF program and
+     * at the same time using APF program {@code apf_program}.  Return {@code true} if
+     * both APF and BPF programs filter out exactly the same packets.
+     */
+    private native static boolean compareBpfApf(String filter, String pcap_filename,
+            byte[] apf_program);
+
+
+    /**
+     * Open packet capture file {@code pcapFilename} and run it through APF filter. Then
+     * checks whether all the packets are dropped and populates data[] {@code data} with
+     * the APF counters.
+     */
+    private native static boolean dropsAllPackets(byte[] program, byte[] data, String pcapFilename);
+
+    @Test
+    public void testBroadcastAddress() throws Exception {
+        assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0));
+        assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32));
+        assertEqualsIp("0.0.3.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 22));
+        assertEqualsIp("0.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 8));
+
+        assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 0));
+        assertEqualsIp("10.0.0.1", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 32));
+        assertEqualsIp("10.0.0.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 24));
+        assertEqualsIp("10.0.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 16));
+    }
+
+    public void assertEqualsIp(String expected, int got) throws Exception {
+        int want = bytesToBEInt(InetAddress.getByName(expected).getAddress());
+        assertEquals(want, got);
+    }
+}
diff --git a/tests/src/android/net/apf/Bpf2Apf.java b/tests/src/android/net/apf/Bpf2Apf.java
new file mode 100644
index 0000000..5d57cde
--- /dev/null
+++ b/tests/src/android/net/apf/Bpf2Apf.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2015 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.apf;
+
+import android.net.apf.ApfGenerator;
+import android.net.apf.ApfGenerator.IllegalInstructionException;
+import android.net.apf.ApfGenerator.Register;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * BPF to APF translator.
+ *
+ * Note: This is for testing purposes only and is not guaranteed to support
+ *       translation of all BPF programs.
+ *
+ * Example usage:
+ *   javac net/java/android/net/apf/ApfGenerator.java \
+ *         tests/servicestests/src/android/net/apf/Bpf2Apf.java
+ *   sudo tcpdump -i em1 -d icmp | java -classpath tests/servicestests/src:net/java \
+ *                                      android.net.apf.Bpf2Apf
+ */
+public class Bpf2Apf {
+    private static int parseImm(String line, String arg) {
+        if (!arg.startsWith("#0x")) {
+            throw new IllegalArgumentException("Unhandled instruction: " + line);
+        }
+        final long val_long = Long.parseLong(arg.substring(3), 16);
+        if (val_long < 0 || val_long > Long.parseLong("ffffffff", 16)) {
+            throw new IllegalArgumentException("Unhandled instruction: " + line);
+        }
+        return new Long((val_long << 32) >> 32).intValue();
+    }
+
+    /**
+     * Convert a single line of "tcpdump -d" (human readable BPF program dump) {@code line} into
+     * APF instruction(s) and append them to {@code gen}. Here's an example line:
+     * (001) jeq      #0x86dd          jt 2    jf 7
+     */
+    private static void convertLine(String line, ApfGenerator gen)
+            throws IllegalInstructionException {
+        if (line.indexOf("(") != 0 || line.indexOf(")") != 4 || line.indexOf(" ") != 5) {
+            throw new IllegalArgumentException("Unhandled instruction: " + line);
+        }
+        int label = Integer.parseInt(line.substring(1, 4));
+        gen.defineLabel(Integer.toString(label));
+        String opcode = line.substring(6, 10).trim();
+        String arg = line.substring(15, Math.min(32, line.length())).trim();
+        switch (opcode) {
+            case "ld":
+            case "ldh":
+            case "ldb":
+            case "ldx":
+            case "ldxb":
+            case "ldxh":
+                Register dest = opcode.contains("x") ? Register.R1 : Register.R0;
+                if (arg.equals("4*([14]&0xf)")) {
+                    if (!opcode.equals("ldxb")) {
+                        throw new IllegalArgumentException("Unhandled instruction: " + line);
+                    }
+                    gen.addLoadFromMemory(dest, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
+                    break;
+                }
+                if (arg.equals("#pktlen")) {
+                    if (!opcode.equals("ld")) {
+                        throw new IllegalArgumentException("Unhandled instruction: " + line);
+                    }
+                    gen.addLoadFromMemory(dest, gen.PACKET_SIZE_MEMORY_SLOT);
+                    break;
+                }
+                if (arg.startsWith("#0x")) {
+                    if (!opcode.equals("ld")) {
+                        throw new IllegalArgumentException("Unhandled instruction: " + line);
+                    }
+                    gen.addLoadImmediate(dest, parseImm(line, arg));
+                    break;
+                }
+                if (arg.startsWith("M[")) {
+                    if (!opcode.startsWith("ld")) {
+                        throw new IllegalArgumentException("Unhandled instruction: " + line);
+                    }
+                    int memory_slot = Integer.parseInt(arg.substring(2, arg.length() - 1));
+                    if (memory_slot < 0 || memory_slot >= gen.MEMORY_SLOTS ||
+                            // Disallow use of pre-filled slots as BPF programs might
+                            // wrongfully assume they're initialized to 0.
+                            (memory_slot >= gen.FIRST_PREFILLED_MEMORY_SLOT &&
+                                    memory_slot <= gen.LAST_PREFILLED_MEMORY_SLOT)) {
+                        throw new IllegalArgumentException("Unhandled instruction: " + line);
+                    }
+                    gen.addLoadFromMemory(dest, memory_slot);
+                    break;
+                }
+                if (arg.startsWith("[x + ")) {
+                    int offset = Integer.parseInt(arg.substring(5, arg.length() - 1));
+                    switch (opcode) {
+                        case "ld":
+                        case "ldx":
+                            gen.addLoad32Indexed(dest, offset);
+                            break;
+                        case "ldh":
+                        case "ldxh":
+                            gen.addLoad16Indexed(dest, offset);
+                            break;
+                        case "ldb":
+                        case "ldxb":
+                            gen.addLoad8Indexed(dest, offset);
+                            break;
+                    }
+                } else {
+                    int offset = Integer.parseInt(arg.substring(1, arg.length() - 1));
+                    switch (opcode) {
+                        case "ld":
+                        case "ldx":
+                            gen.addLoad32(dest, offset);
+                            break;
+                        case "ldh":
+                        case "ldxh":
+                            gen.addLoad16(dest, offset);
+                            break;
+                        case "ldb":
+                        case "ldxb":
+                            gen.addLoad8(dest, offset);
+                            break;
+                    }
+                }
+                break;
+            case "st":
+            case "stx":
+                Register src = opcode.contains("x") ? Register.R1 : Register.R0;
+                if (!arg.startsWith("M[")) {
+                    throw new IllegalArgumentException("Unhandled instruction: " + line);
+                }
+                int memory_slot = Integer.parseInt(arg.substring(2, arg.length() - 1));
+                if (memory_slot < 0 || memory_slot >= gen.MEMORY_SLOTS ||
+                        // Disallow overwriting pre-filled slots
+                        (memory_slot >= gen.FIRST_PREFILLED_MEMORY_SLOT &&
+                                memory_slot <= gen.LAST_PREFILLED_MEMORY_SLOT)) {
+                    throw new IllegalArgumentException("Unhandled instruction: " + line);
+                }
+                gen.addStoreToMemory(src, memory_slot);
+                break;
+            case "add":
+            case "and":
+            case "or":
+            case "sub":
+                if (arg.equals("x")) {
+                    switch(opcode) {
+                        case "add":
+                            gen.addAddR1();
+                            break;
+                        case "and":
+                            gen.addAndR1();
+                            break;
+                        case "or":
+                            gen.addOrR1();
+                            break;
+                        case "sub":
+                            gen.addNeg(Register.R1);
+                            gen.addAddR1();
+                            gen.addNeg(Register.R1);
+                            break;
+                    }
+                } else {
+                    int imm = parseImm(line, arg);
+                    switch(opcode) {
+                        case "add":
+                            gen.addAdd(imm);
+                            break;
+                        case "and":
+                            gen.addAnd(imm);
+                            break;
+                        case "or":
+                            gen.addOr(imm);
+                            break;
+                        case "sub":
+                            gen.addAdd(-imm);
+                            break;
+                    }
+                }
+                break;
+            case "jeq":
+            case "jset":
+            case "jgt":
+            case "jge":
+                int val = 0;
+                boolean reg_compare;
+                if (arg.startsWith("x")) {
+                    reg_compare = true;
+                } else {
+                    reg_compare = false;
+                    val = parseImm(line, arg);
+                }
+                int jt_offset = line.indexOf("jt");
+                int jf_offset = line.indexOf("jf");
+                String true_label = line.substring(jt_offset + 2, jf_offset).trim();
+                String false_label = line.substring(jf_offset + 2).trim();
+                boolean true_label_is_fallthrough = Integer.parseInt(true_label) == label + 1;
+                boolean false_label_is_fallthrough = Integer.parseInt(false_label) == label + 1;
+                if (true_label_is_fallthrough && false_label_is_fallthrough)
+                    break;
+                switch (opcode) {
+                    case "jeq":
+                        if (!true_label_is_fallthrough) {
+                            if (reg_compare) {
+                                gen.addJumpIfR0EqualsR1(true_label);
+                            } else {
+                                gen.addJumpIfR0Equals(val, true_label);
+                            }
+                        }
+                        if (!false_label_is_fallthrough) {
+                            if (!true_label_is_fallthrough) {
+                                gen.addJump(false_label);
+                            } else if (reg_compare) {
+                                gen.addJumpIfR0NotEqualsR1(false_label);
+                            } else {
+                                gen.addJumpIfR0NotEquals(val, false_label);
+                            }
+                        }
+                        break;
+                    case "jset":
+                        if (reg_compare) {
+                            gen.addJumpIfR0AnyBitsSetR1(true_label);
+                        } else {
+                            gen.addJumpIfR0AnyBitsSet(val, true_label);
+                        }
+                        if (!false_label_is_fallthrough) {
+                            gen.addJump(false_label);
+                        }
+                        break;
+                    case "jgt":
+                        if (!true_label_is_fallthrough ||
+                                // We have no less-than-or-equal-to register to register
+                                // comparison instruction, so in this case we'll jump
+                                // around an unconditional jump.
+                                (!false_label_is_fallthrough && reg_compare)) {
+                            if (reg_compare) {
+                                gen.addJumpIfR0GreaterThanR1(true_label);
+                            } else {
+                                gen.addJumpIfR0GreaterThan(val, true_label);
+                            }
+                        }
+                        if (!false_label_is_fallthrough) {
+                            if (!true_label_is_fallthrough || reg_compare) {
+                                gen.addJump(false_label);
+                            } else {
+                                gen.addJumpIfR0LessThan(val + 1, false_label);
+                            }
+                        }
+                        break;
+                    case "jge":
+                        if (!false_label_is_fallthrough ||
+                                // We have no greater-than-or-equal-to register to register
+                                // comparison instruction, so in this case we'll jump
+                                // around an unconditional jump.
+                                (!true_label_is_fallthrough && reg_compare)) {
+                            if (reg_compare) {
+                                gen.addJumpIfR0LessThanR1(false_label);
+                            } else {
+                                gen.addJumpIfR0LessThan(val, false_label);
+                            }
+                        }
+                        if (!true_label_is_fallthrough) {
+                            if (!false_label_is_fallthrough || reg_compare) {
+                                gen.addJump(true_label);
+                            } else {
+                                gen.addJumpIfR0GreaterThan(val - 1, true_label);
+                            }
+                        }
+                        break;
+                }
+                break;
+            case "ret":
+                if (arg.equals("#0")) {
+                    gen.addJump(gen.DROP_LABEL);
+                } else {
+                    gen.addJump(gen.PASS_LABEL);
+                }
+                break;
+            case "tax":
+                gen.addMove(Register.R1);
+                break;
+            case "txa":
+                gen.addMove(Register.R0);
+                break;
+            default:
+                throw new IllegalArgumentException("Unhandled instruction: " + line);
+        }
+    }
+
+    /**
+     * Convert the output of "tcpdump -d" (human readable BPF program dump) {@code bpf} into an APF
+     * program and return it.
+     */
+    public static byte[] convert(String bpf) throws IllegalInstructionException {
+        ApfGenerator gen = new ApfGenerator(3);
+        for (String line : bpf.split("\\n")) convertLine(line, gen);
+        return gen.generate();
+    }
+
+    /**
+     * Convert the output of "tcpdump -d" (human readable BPF program dump) piped in stdin into an
+     * APF program and output it via stdout.
+     */
+    public static void main(String[] args) throws Exception {
+        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+        String line = null;
+        StringBuilder responseData = new StringBuilder();
+        ApfGenerator gen = new ApfGenerator(3);
+        while ((line = in.readLine()) != null) convertLine(line, gen);
+        System.out.write(gen.generate());
+    }
+}
diff --git a/tests/src/android/net/dhcp/DhcpPacketTest.java b/tests/src/android/net/dhcp/DhcpPacketTest.java
new file mode 100644
index 0000000..a592809
--- /dev/null
+++ b/tests/src/android/net/dhcp/DhcpPacketTest.java
@@ -0,0 +1,1075 @@
+/*
+ * Copyright (C) 2015 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.getBroadcastAddress;
+import static android.net.NetworkUtils.getPrefixMaskAsInet4Address;
+import static android.net.dhcp.DhcpPacket.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.annotation.Nullable;
+import android.net.DhcpResults;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+import android.net.metrics.DhcpErrorEvent;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
+
+import com.android.internal.util.HexDump;
+
+import java.io.ByteArrayOutputStream;
+import java.net.Inet4Address;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Random;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DhcpPacketTest {
+
+    private static final Inet4Address SERVER_ADDR = v4Address("192.0.2.1");
+    private static final Inet4Address CLIENT_ADDR = v4Address("192.0.2.234");
+    private static final int PREFIX_LENGTH = 22;
+    private static final Inet4Address NETMASK = getPrefixMaskAsInet4Address(PREFIX_LENGTH);
+    private static final Inet4Address BROADCAST_ADDR = getBroadcastAddress(
+            SERVER_ADDR, PREFIX_LENGTH);
+    private static final String HOSTNAME = "testhostname";
+    private static final short MTU = 1500;
+    // Use our own empty address instead of Inet4Address.ANY or INADDR_ANY to ensure that the code
+    // doesn't use == instead of equals when comparing addresses.
+    private static final Inet4Address ANY = (Inet4Address) v4Address("0.0.0.0");
+
+    private static final byte[] CLIENT_MAC = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+
+    private static final Inet4Address v4Address(String addrString) throws IllegalArgumentException {
+        return (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
+    }
+
+    @Before
+    public void setUp() {
+        DhcpPacket.testOverrideVendorId = "android-dhcp-???";
+        DhcpPacket.testOverrideHostname = "android-01234567890abcde";
+    }
+
+    class TestDhcpPacket extends DhcpPacket {
+        private byte mType;
+        // TODO: Make this a map of option numbers to bytes instead.
+        private byte[] mDomainBytes, mVendorInfoBytes, mLeaseTimeBytes, mNetmaskBytes;
+
+        public TestDhcpPacket(byte type, Inet4Address clientIp, Inet4Address yourIp) {
+            super(0xdeadbeef, (short) 0, clientIp, yourIp, INADDR_ANY, INADDR_ANY,
+                  CLIENT_MAC, true);
+            mType = type;
+        }
+
+        public TestDhcpPacket(byte type) {
+            this(type, INADDR_ANY, CLIENT_ADDR);
+        }
+
+        public TestDhcpPacket setDomainBytes(byte[] domainBytes) {
+            mDomainBytes = domainBytes;
+            return this;
+        }
+
+        public TestDhcpPacket setVendorInfoBytes(byte[] vendorInfoBytes) {
+            mVendorInfoBytes = vendorInfoBytes;
+            return this;
+        }
+
+        public TestDhcpPacket setLeaseTimeBytes(byte[] leaseTimeBytes) {
+            mLeaseTimeBytes = leaseTimeBytes;
+            return this;
+        }
+
+        public TestDhcpPacket setNetmaskBytes(byte[] netmaskBytes) {
+            mNetmaskBytes = netmaskBytes;
+            return this;
+        }
+
+        public ByteBuffer buildPacket(int encap, short unusedDestUdp, short unusedSrcUdp) {
+            ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
+            fillInPacket(encap, CLIENT_ADDR, SERVER_ADDR,
+                         DHCP_CLIENT, DHCP_SERVER, result, DHCP_BOOTREPLY, false);
+            return result;
+        }
+
+        public void finishPacket(ByteBuffer buffer) {
+            addTlv(buffer, DHCP_MESSAGE_TYPE, mType);
+            if (mDomainBytes != null) {
+                addTlv(buffer, DHCP_DOMAIN_NAME, mDomainBytes);
+            }
+            if (mVendorInfoBytes != null) {
+                addTlv(buffer, DHCP_VENDOR_INFO, mVendorInfoBytes);
+            }
+            if (mLeaseTimeBytes != null) {
+                addTlv(buffer, DHCP_LEASE_TIME, mLeaseTimeBytes);
+            }
+            if (mNetmaskBytes != null) {
+                addTlv(buffer, DHCP_SUBNET_MASK, mNetmaskBytes);
+            }
+            addTlvEnd(buffer);
+        }
+
+        // Convenience method.
+        public ByteBuffer build() {
+            // ENCAP_BOOTP packets don't contain ports, so just pass in 0.
+            ByteBuffer pkt = buildPacket(ENCAP_BOOTP, (short) 0, (short) 0);
+            pkt.flip();
+            return pkt;
+        }
+    }
+
+    private void assertDomainAndVendorInfoParses(
+            String expectedDomain, byte[] domainBytes,
+            String expectedVendorInfo, byte[] vendorInfoBytes) throws Exception {
+        ByteBuffer packet = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER)
+                .setDomainBytes(domainBytes)
+                .setVendorInfoBytes(vendorInfoBytes)
+                .build();
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+        assertEquals(expectedDomain, offerPacket.mDomainName);
+        assertEquals(expectedVendorInfo, offerPacket.mVendorInfo);
+    }
+
+    @Test
+    public void testDomainName() throws Exception {
+        byte[] nullByte = new byte[] { 0x00 };
+        byte[] twoNullBytes = new byte[] { 0x00, 0x00 };
+        byte[] nonNullDomain = new byte[] {
+            (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l'
+        };
+        byte[] trailingNullDomain = new byte[] {
+            (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l', 0x00
+        };
+        byte[] embeddedNullsDomain = new byte[] {
+            (byte) 'g', (byte) 'o', (byte) 'o', 0x00, 0x00, (byte) 'g', (byte) 'l'
+        };
+        byte[] metered = "ANDROID_METERED".getBytes("US-ASCII");
+
+        byte[] meteredEmbeddedNull = metered.clone();
+        meteredEmbeddedNull[7] = (char) 0;
+
+        byte[] meteredTrailingNull = metered.clone();
+        meteredTrailingNull[meteredTrailingNull.length - 1] = (char) 0;
+
+        assertDomainAndVendorInfoParses("", nullByte, "\u0000", nullByte);
+        assertDomainAndVendorInfoParses("", twoNullBytes, "\u0000\u0000", twoNullBytes);
+        assertDomainAndVendorInfoParses("goo.gl", nonNullDomain, "ANDROID_METERED", metered);
+        assertDomainAndVendorInfoParses("goo", embeddedNullsDomain,
+                                        "ANDROID\u0000METERED", meteredEmbeddedNull);
+        assertDomainAndVendorInfoParses("goo.gl", trailingNullDomain,
+                                        "ANDROID_METERE\u0000", meteredTrailingNull);
+    }
+
+    private void assertLeaseTimeParses(boolean expectValid, Integer rawLeaseTime,
+            long leaseTimeMillis, byte[] leaseTimeBytes) throws Exception {
+        TestDhcpPacket testPacket = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER);
+        if (leaseTimeBytes != null) {
+            testPacket.setLeaseTimeBytes(leaseTimeBytes);
+        }
+        ByteBuffer packet = testPacket.build();
+        DhcpPacket offerPacket = null;
+
+        if (!expectValid) {
+            try {
+                offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+                fail("Invalid packet parsed successfully: " + offerPacket);
+            } catch (ParseException expected) {
+            }
+            return;
+        }
+
+        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+        assertNotNull(offerPacket);
+        assertEquals(rawLeaseTime, offerPacket.mLeaseTime);
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();  // Just check this doesn't crash.
+        assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis());
+    }
+
+    @Test
+    public void testLeaseTime() throws Exception {
+        byte[] noLease = null;
+        byte[] tooShortLease = new byte[] { 0x00, 0x00 };
+        byte[] tooLongLease = new byte[] { 0x00, 0x00, 0x00, 60, 0x01 };
+        byte[] zeroLease = new byte[] { 0x00, 0x00, 0x00, 0x00 };
+        byte[] tenSecondLease = new byte[] { 0x00, 0x00, 0x00, 10 };
+        byte[] oneMinuteLease = new byte[] { 0x00, 0x00, 0x00, 60 };
+        byte[] fiveMinuteLease = new byte[] { 0x00, 0x00, 0x01, 0x2c };
+        byte[] oneDayLease = new byte[] { 0x00, 0x01, 0x51, (byte) 0x80 };
+        byte[] maxIntPlusOneLease = new byte[] { (byte) 0x80, 0x00, 0x00, 0x01 };
+        byte[] infiniteLease = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
+
+        assertLeaseTimeParses(true, null, 0, noLease);
+        assertLeaseTimeParses(false, null, 0, tooShortLease);
+        assertLeaseTimeParses(false, null, 0, tooLongLease);
+        assertLeaseTimeParses(true, 0, 60 * 1000, zeroLease);
+        assertLeaseTimeParses(true, 10, 60 * 1000, tenSecondLease);
+        assertLeaseTimeParses(true, 60, 60 * 1000, oneMinuteLease);
+        assertLeaseTimeParses(true, 300, 300 * 1000, fiveMinuteLease);
+        assertLeaseTimeParses(true, 86400, 86400 * 1000, oneDayLease);
+        assertLeaseTimeParses(true, -2147483647, 2147483649L * 1000, maxIntPlusOneLease);
+        assertLeaseTimeParses(true, DhcpPacket.INFINITE_LEASE, 0, infiniteLease);
+    }
+
+    private void checkIpAddress(String expected, Inet4Address clientIp, Inet4Address yourIp,
+                                byte[] netmaskBytes) throws Exception {
+        checkIpAddress(expected, DHCP_MESSAGE_TYPE_OFFER, clientIp, yourIp, netmaskBytes);
+        checkIpAddress(expected, DHCP_MESSAGE_TYPE_ACK, clientIp, yourIp, netmaskBytes);
+    }
+
+    private void checkIpAddress(String expected, byte type,
+                                Inet4Address clientIp, Inet4Address yourIp,
+                                byte[] netmaskBytes) throws Exception {
+        ByteBuffer packet = new TestDhcpPacket(type, clientIp, yourIp)
+                .setNetmaskBytes(netmaskBytes)
+                .build();
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+        DhcpResults results = offerPacket.toDhcpResults();
+
+        if (expected != null) {
+            LinkAddress expectedAddress = new LinkAddress(expected);
+            assertEquals(expectedAddress, results.ipAddress);
+        } else {
+            assertNull(results);
+        }
+    }
+
+    @Test
+    public void testIpAddress() throws Exception {
+        byte[] slash11Netmask = new byte[] { (byte) 0xff, (byte) 0xe0, 0x00, 0x00 };
+        byte[] slash24Netmask = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00 };
+        byte[] invalidNetmask = new byte[] { (byte) 0xff, (byte) 0xfb, (byte) 0xff, 0x00 };
+        Inet4Address example1 = v4Address("192.0.2.1");
+        Inet4Address example2 = v4Address("192.0.2.43");
+
+        // A packet without any addresses is not valid.
+        checkIpAddress(null, ANY, ANY, slash24Netmask);
+
+        // ClientIP is used iff YourIP is not present.
+        checkIpAddress("192.0.2.1/24", example2, example1, slash24Netmask);
+        checkIpAddress("192.0.2.43/11", example2, ANY, slash11Netmask);
+        checkIpAddress("192.0.2.43/11", ANY, example2, slash11Netmask);
+
+        // Invalid netmasks are ignored.
+        checkIpAddress(null, example2, ANY, invalidNetmask);
+
+        // If there is no netmask, implicit netmasks are used.
+        checkIpAddress("192.0.2.43/24", ANY, example2, null);
+    }
+
+    private void assertDhcpResults(String ipAddress, String gateway, String dnsServersString,
+            String domains, String serverAddress, String vendorInfo, int leaseDuration,
+            boolean hasMeteredHint, int mtu, DhcpResults dhcpResults) throws Exception {
+        assertEquals(new LinkAddress(ipAddress), dhcpResults.ipAddress);
+        assertEquals(v4Address(gateway), dhcpResults.gateway);
+
+        String[] dnsServerStrings = dnsServersString.split(",");
+        ArrayList dnsServers = new ArrayList();
+        for (String dnsServerString : dnsServerStrings) {
+            dnsServers.add(v4Address(dnsServerString));
+        }
+        assertEquals(dnsServers, dhcpResults.dnsServers);
+
+        assertEquals(domains, dhcpResults.domains);
+        assertEquals(v4Address(serverAddress), dhcpResults.serverAddress);
+        assertEquals(vendorInfo, dhcpResults.vendorInfo);
+        assertEquals(leaseDuration, dhcpResults.leaseDuration);
+        assertEquals(hasMeteredHint, dhcpResults.hasMeteredHint());
+        assertEquals(mtu, dhcpResults.mtu);
+    }
+
+    @Test
+    public void testOffer1() throws Exception {
+        // TODO: Turn all of these into golden files. This will probably require using
+        // android.support.test.InstrumentationRegistry for obtaining a Context object
+        // to read such golden files, along with an appropriate Android.mk.
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // IP header.
+            "451001480000000080118849c0a89003c0a89ff7" +
+            // UDP header.
+            "004300440134dcfa" +
+            // BOOTP header.
+            "02010600c997a63b0000000000000000c0a89ff70000000000000000" +
+            // MAC address.
+            "30766ff2a90c00000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options
+            "638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
+            "3a0400000e103b040000189cff00000000000000000000"));
+
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();
+        assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
+                null, "192.168.144.3", null, 7200, false, 0, dhcpResults);
+    }
+
+    @Test
+    public void testOffer2() throws Exception {
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // IP header.
+            "450001518d0600004011144dc0a82b01c0a82bf7" +
+            // UDP header.
+            "00430044013d9ac7" +
+            // BOOTP header.
+            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
+            // MAC address.
+            "30766ff2a90c00000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options
+            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
+            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
+
+        assertEquals(337, packet.limit());
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();
+        assertDhcpResults("192.168.43.247/24", "192.168.43.1", "192.168.43.1",
+                null, "192.168.43.1", "ANDROID_METERED", 3600, true, 0, dhcpResults);
+        assertTrue(dhcpResults.hasMeteredHint());
+    }
+
+    @Test
+    public void testBadIpPacket() throws Exception {
+        final byte[] packet = HexDump.hexStringToByteArray(
+            // IP header.
+            "450001518d0600004011144dc0a82b01c0a82bf7");
+
+        try {
+            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
+        } catch (DhcpPacket.ParseException expected) {
+            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
+            return;
+        }
+        fail("Dhcp packet parsing should have failed");
+    }
+
+    @Test
+    public void testBadDhcpPacket() throws Exception {
+        final byte[] packet = HexDump.hexStringToByteArray(
+            // IP header.
+            "450001518d0600004011144dc0a82b01c0a82bf7" +
+            // UDP header.
+            "00430044013d9ac7" +
+            // BOOTP header.
+            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000");
+
+        try {
+            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
+        } catch (DhcpPacket.ParseException expected) {
+            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
+            return;
+        }
+        fail("Dhcp packet parsing should have failed");
+    }
+
+    @Test
+    public void testBadTruncatedOffer() throws Exception {
+        final byte[] packet = HexDump.hexStringToByteArray(
+            // IP header.
+            "450001518d0600004011144dc0a82b01c0a82bf7" +
+            // UDP header.
+            "00430044013d9ac7" +
+            // BOOTP header.
+            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
+            // MAC address.
+            "30766ff2a90c00000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File, missing one byte
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "00000000000000000000000000000000000000000000000000000000000000");
+
+        try {
+            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
+        } catch (DhcpPacket.ParseException expected) {
+            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
+            return;
+        }
+        fail("Dhcp packet parsing should have failed");
+    }
+
+    @Test
+    public void testBadOfferWithoutACookie() throws Exception {
+        final byte[] packet = HexDump.hexStringToByteArray(
+            // IP header.
+            "450001518d0600004011144dc0a82b01c0a82bf7" +
+            // UDP header.
+            "00430044013d9ac7" +
+            // BOOTP header.
+            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
+            // MAC address.
+            "30766ff2a90c00000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000"
+            // No options
+            );
+
+        try {
+            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
+        } catch (DhcpPacket.ParseException expected) {
+            assertDhcpErrorCodes(DhcpErrorEvent.DHCP_NO_COOKIE, expected.errorCode);
+            return;
+        }
+        fail("Dhcp packet parsing should have failed");
+    }
+
+    @Test
+    public void testOfferWithBadCookie() throws Exception {
+        final byte[] packet = HexDump.hexStringToByteArray(
+            // IP header.
+            "450001518d0600004011144dc0a82b01c0a82bf7" +
+            // UDP header.
+            "00430044013d9ac7" +
+            // BOOTP header.
+            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
+            // MAC address.
+            "30766ff2a90c00000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Bad cookie
+            "DEADBEEF3501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
+            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff");
+
+        try {
+            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
+        } catch (DhcpPacket.ParseException expected) {
+            assertDhcpErrorCodes(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE, expected.errorCode);
+            return;
+        }
+        fail("Dhcp packet parsing should have failed");
+    }
+
+    private void assertDhcpErrorCodes(int expected, int got) {
+        assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
+    }
+
+    @Test
+    public void testTruncatedOfferPackets() throws Exception {
+        final byte[] packet = HexDump.hexStringToByteArray(
+            // IP header.
+            "450001518d0600004011144dc0a82b01c0a82bf7" +
+            // UDP header.
+            "00430044013d9ac7" +
+            // BOOTP header.
+            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
+            // MAC address.
+            "30766ff2a90c00000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options
+            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
+            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff");
+
+        for (int len = 0; len < packet.length; len++) {
+            try {
+                DhcpPacket.decodeFullPacket(packet, len, ENCAP_L3);
+            } catch (ParseException e) {
+                if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
+                    fail(String.format("bad truncated packet of length %d", len));
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testRandomPackets() throws Exception {
+        final int maxRandomPacketSize = 512;
+        final Random r = new Random();
+        for (int i = 0; i < 10000; i++) {
+            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
+            r.nextBytes(packet);
+            try {
+                DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
+            } catch (ParseException e) {
+                if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
+                    fail("bad packet: " + HexDump.toHexString(packet));
+                }
+            }
+        }
+    }
+
+    private byte[] mtuBytes(int mtu) {
+        // 0x1a02: option 26, length 2. 0xff: no more options.
+        if (mtu > Short.MAX_VALUE - Short.MIN_VALUE) {
+            throw new IllegalArgumentException(
+                String.format("Invalid MTU %d, must be 16-bit unsigned", mtu));
+        }
+        String hexString = String.format("1a02%04xff", mtu);
+        return HexDump.hexStringToByteArray(hexString);
+    }
+
+    private void checkMtu(ByteBuffer packet, int expectedMtu, byte[] mtuBytes) throws Exception {
+        if (mtuBytes != null) {
+            packet.position(packet.capacity() - mtuBytes.length);
+            packet.put(mtuBytes);
+            packet.clear();
+        }
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();
+        assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
+                null, "192.168.144.3", null, 7200, false, expectedMtu, dhcpResults);
+    }
+
+    @Test
+    public void testMtu() throws Exception {
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // IP header.
+            "451001480000000080118849c0a89003c0a89ff7" +
+            // UDP header.
+            "004300440134dcfa" +
+            // BOOTP header.
+            "02010600c997a63b0000000000000000c0a89ff70000000000000000" +
+            // MAC address.
+            "30766ff2a90c00000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options
+            "638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
+            "3a0400000e103b040000189cff00000000"));
+
+        checkMtu(packet, 0, null);
+        checkMtu(packet, 0, mtuBytes(1501));
+        checkMtu(packet, 1500, mtuBytes(1500));
+        checkMtu(packet, 1499, mtuBytes(1499));
+        checkMtu(packet, 1280, mtuBytes(1280));
+        checkMtu(packet, 0, mtuBytes(1279));
+        checkMtu(packet, 0, mtuBytes(576));
+        checkMtu(packet, 0, mtuBytes(68));
+        checkMtu(packet, 0, mtuBytes(Short.MIN_VALUE));
+        checkMtu(packet, 0, mtuBytes(Short.MAX_VALUE + 3));
+        checkMtu(packet, 0, mtuBytes(-1));
+    }
+
+    @Test
+    public void testBadHwaddrLength() throws Exception {
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // IP header.
+            "450001518d0600004011144dc0a82b01c0a82bf7" +
+            // UDP header.
+            "00430044013d9ac7" +
+            // BOOTP header.
+            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
+            // MAC address.
+            "30766ff2a90c00000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options
+            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
+            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
+        String expectedClientMac = "30766FF2A90C";
+
+        final int hwAddrLenOffset = 20 + 8 + 2;
+        assertEquals(6, packet.get(hwAddrLenOffset));
+
+        // Expect the expected.
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(6, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
+
+        // Reduce the hardware address length and verify that it shortens the client MAC.
+        packet.flip();
+        packet.put(hwAddrLenOffset, (byte) 5);
+        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(5, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac.substring(0, 10),
+                HexDump.toHexString(offerPacket.getClientMac()));
+
+        packet.flip();
+        packet.put(hwAddrLenOffset, (byte) 3);
+        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(3, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac.substring(0, 6),
+                HexDump.toHexString(offerPacket.getClientMac()));
+
+        // Set the the hardware address length to 0xff and verify that we a) don't treat it as -1
+        // and crash, and b) hardcode it to 6.
+        packet.flip();
+        packet.put(hwAddrLenOffset, (byte) -1);
+        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(6, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
+
+        // Set the the hardware address length to a positive invalid value (> 16) and verify that we
+        // hardcode it to 6.
+        packet.flip();
+        packet.put(hwAddrLenOffset, (byte) 17);
+        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertNotNull(offerPacket);
+        assertEquals(6, offerPacket.getClientMac().length);
+        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
+    }
+
+    @Test
+    public void testPadAndOverloadedOptionsOffer() throws Exception {
+        // A packet observed in the real world that is interesting for two reasons:
+        //
+        // 1. It uses pad bytes, which we previously didn't support correctly.
+        // 2. It uses DHCP option overloading, which we don't currently support (but it doesn't
+        //    store any information in the overloaded fields).
+        //
+        // For now, we just check that it parses correctly.
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // Ethernet header.
+            "b4cef6000000e80462236e300800" +
+            // IP header.
+            "4500014c00000000ff11741701010101ac119876" +
+            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+            "004300440138ae5a" +
+            // BOOTP header.
+            "020106000fa0059f0000000000000000ac1198760000000000000000" +
+            // MAC address.
+            "b4cef600000000000000000000000000" +
+            // Server name.
+            "ff00000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "ff00000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options
+            "638253633501023604010101010104ffff000033040000a8c03401030304ac1101010604ac110101" +
+            "0000000000000000000000000000000000000000000000ff000000"));
+
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
+        assertTrue(offerPacket instanceof DhcpOfferPacket);
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();
+        assertDhcpResults("172.17.152.118/16", "172.17.1.1", "172.17.1.1",
+                null, "1.1.1.1", null, 43200, false, 0, dhcpResults);
+    }
+
+    @Test
+    public void testBug2111() throws Exception {
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // IP header.
+            "4500014c00000000ff119beac3eaf3880a3f5d04" +
+            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+            "0043004401387464" +
+            // BOOTP header.
+            "0201060002554812000a0000000000000a3f5d040000000000000000" +
+            // MAC address.
+            "00904c00000000000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options.
+            "638253633501023604c00002fe33040000bfc60104fffff00003040a3f50010608c0000201c0000202" +
+            "0f0f646f6d61696e3132332e636f2e756b0000000000ff00000000"));
+
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+        assertTrue(offerPacket instanceof DhcpOfferPacket);
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();
+        assertDhcpResults("10.63.93.4/20", "10.63.80.1", "192.0.2.1,192.0.2.2",
+                "domain123.co.uk", "192.0.2.254", null, 49094, false, 0, dhcpResults);
+    }
+
+    @Test
+    public void testBug2136() throws Exception {
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // Ethernet header.
+            "bcf5ac000000d0c7890000000800" +
+            // IP header.
+            "4500014c00000000ff119beac3eaf3880a3f5d04" +
+            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+            "0043004401387574" +
+            // BOOTP header.
+            "0201060163339a3000050000000000000a209ecd0000000000000000" +
+            // MAC address.
+            "bcf5ac00000000000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options.
+            "6382536335010236040a20ff80330400001c200104fffff00003040a20900106089458413494584135" +
+            "0f0b6c616e63732e61632e756b000000000000000000ff00000000"));
+
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
+        assertTrue(offerPacket instanceof DhcpOfferPacket);
+        assertEquals("BCF5AC000000", HexDump.toHexString(offerPacket.getClientMac()));
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();
+        assertDhcpResults("10.32.158.205/20", "10.32.144.1", "148.88.65.52,148.88.65.53",
+                "lancs.ac.uk", "10.32.255.128", null, 7200, false, 0, dhcpResults);
+    }
+
+    @Test
+    public void testUdpServerAnySourcePort() throws Exception {
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // Ethernet header.
+            "9cd917000000001c2e0000000800" +
+            // IP header.
+            "45a00148000040003d115087d18194fb0a0f7af2" +
+            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+            // NOTE: The server source port is not the canonical port 67.
+            "C29F004401341268" +
+            // BOOTP header.
+            "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
+            // MAC address.
+            "9cd91700000000000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options.
+            "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
+            "d18180060f0777766d2e6564751c040a0fffffff000000"));
+
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
+        assertTrue(offerPacket instanceof DhcpOfferPacket);
+        assertEquals("9CD917000000", HexDump.toHexString(offerPacket.getClientMac()));
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();
+        assertDhcpResults("10.15.122.242/16", "10.15.200.23",
+                "209.129.128.3,209.129.148.3,209.129.128.6",
+                "wvm.edu", "10.1.105.252", null, 86400, false, 0, dhcpResults);
+    }
+
+    @Test
+    public void testUdpInvalidDstPort() throws Exception {
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // Ethernet header.
+            "9cd917000000001c2e0000000800" +
+            // IP header.
+            "45a00148000040003d115087d18194fb0a0f7af2" +
+            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+            // NOTE: The destination port is a non-DHCP port.
+            "0043aaaa01341268" +
+            // BOOTP header.
+            "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
+            // MAC address.
+            "9cd91700000000000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options.
+            "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
+            "d18180060f0777766d2e6564751c040a0fffffff000000"));
+
+        try {
+            DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
+            fail("Packet with invalid dst port did not throw ParseException");
+        } catch (ParseException expected) {}
+    }
+
+    @Test
+    public void testMultipleRouters() throws Exception {
+        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
+            // Ethernet header.
+            "fc3d93000000" + "081735000000" + "0800" +
+            // IP header.
+            "45000148c2370000ff117ac2c0a8bd02ffffffff" +
+            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+            "0043004401343beb" +
+            // BOOTP header.
+            "0201060027f518e20000800000000000c0a8bd310000000000000000" +
+            // MAC address.
+            "fc3d9300000000000000000000000000" +
+            // Server name.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // File.
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            "0000000000000000000000000000000000000000000000000000000000000000" +
+            // Options.
+            "638253633501023604c0abbd023304000070803a04000038403b04000062700104ffffff00" +
+            "0308c0a8bd01ffffff0006080808080808080404ff000000000000"));
+
+        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
+        assertTrue(offerPacket instanceof DhcpOfferPacket);
+        assertEquals("FC3D93000000", HexDump.toHexString(offerPacket.getClientMac()));
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();
+        assertDhcpResults("192.168.189.49/24", "192.168.189.1", "8.8.8.8,8.8.4.4",
+                null, "192.171.189.2", null, 28800, false, 0, dhcpResults);
+    }
+
+    @Test
+    public void testDiscoverPacket() throws Exception {
+        short secs = 7;
+        int transactionId = 0xdeadbeef;
+        byte[] hwaddr = {
+                (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a
+        };
+
+        ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
+                DhcpPacket.ENCAP_L2, transactionId, secs, hwaddr,
+                false /* do unicast */, DhcpClient.REQUESTED_PARAMS);
+
+        byte[] headers = new byte[] {
+            // Ethernet header.
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a,
+            (byte) 0x08, (byte) 0x00,
+            // IP header.
+            (byte) 0x45, (byte) 0x10, (byte) 0x01, (byte) 0x56,
+            (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x00,
+            (byte) 0x40, (byte) 0x11, (byte) 0x39, (byte) 0x88,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            // UDP header.
+            (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x43,
+            (byte) 0x01, (byte) 0x42, (byte) 0x6a, (byte) 0x4a,
+            // BOOTP.
+            (byte) 0x01, (byte) 0x01, (byte) 0x06, (byte) 0x00,
+            (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
+            (byte) 0x00, (byte) 0x07, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b,
+            (byte) 0xb1, (byte) 0x7a
+        };
+        byte[] options = new byte[] {
+            // Magic cookie 0x63825363.
+            (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
+            // Message type DISCOVER.
+            (byte) 0x35, (byte) 0x01, (byte) 0x01,
+            // Client identifier Ethernet, da:01:19:5b:b1:7a.
+            (byte) 0x3d, (byte) 0x07,
+                    (byte) 0x01,
+                    (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a,
+            // Max message size 1500.
+            (byte) 0x39, (byte) 0x02, (byte) 0x05, (byte) 0xdc,
+            // Version "android-dhcp-???".
+            (byte) 0x3c, (byte) 0x10,
+                    'a', 'n', 'd', 'r', 'o', 'i', 'd', '-', 'd', 'h', 'c', 'p', '-', '?', '?', '?',
+            // Hostname "android-01234567890abcde"
+            (byte) 0x0c, (byte) 0x18,
+                    'a', 'n', 'd', 'r', 'o', 'i', 'd', '-',
+                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e',
+            // Requested parameter list.
+            (byte) 0x37, (byte) 0x0a,
+                DHCP_SUBNET_MASK,
+                DHCP_ROUTER,
+                DHCP_DNS_SERVER,
+                DHCP_DOMAIN_NAME,
+                DHCP_MTU,
+                DHCP_BROADCAST_ADDRESS,
+                DHCP_LEASE_TIME,
+                DHCP_RENEWAL_TIME,
+                DHCP_REBINDING_TIME,
+                DHCP_VENDOR_INFO,
+            // End options.
+            (byte) 0xff,
+            // Our packets are always of even length. TODO: find out why and possibly fix it.
+            (byte) 0x00
+        };
+        byte[] expected = new byte[DhcpPacket.MIN_PACKET_LENGTH_L2 + options.length];
+        assertTrue((expected.length & 1) == 0);
+        System.arraycopy(headers, 0, expected, 0, headers.length);
+        System.arraycopy(options, 0, expected, DhcpPacket.MIN_PACKET_LENGTH_L2, options.length);
+
+        byte[] actual = new byte[packet.limit()];
+        packet.get(actual);
+        String msg =
+                "Expected:\n  " + Arrays.toString(expected) +
+                "\nActual:\n  " + Arrays.toString(actual);
+        assertTrue(msg, Arrays.equals(expected, actual));
+    }
+
+    public void checkBuildOfferPacket(int leaseTimeSecs, @Nullable String hostname)
+            throws Exception {
+        final int renewalTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) / 2);
+        final int rebindingTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) * 875 / 1000);
+        final int transactionId = 0xdeadbeef;
+
+        final ByteBuffer packet = DhcpPacket.buildOfferPacket(
+                DhcpPacket.ENCAP_BOOTP, transactionId, false /* broadcast */,
+                SERVER_ADDR, INADDR_ANY /* relayIp */, CLIENT_ADDR /* yourIp */,
+                CLIENT_MAC, leaseTimeSecs, NETMASK /* netMask */,
+                BROADCAST_ADDR /* bcAddr */, Collections.singletonList(SERVER_ADDR) /* gateways */,
+                Collections.singletonList(SERVER_ADDR) /* dnsServers */,
+                SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, hostname,
+                false /* metered */, MTU);
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        // BOOTP headers
+        bos.write(new byte[] {
+                (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x00,
+                (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // ciaddr
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        });
+        // yiaddr
+        bos.write(CLIENT_ADDR.getAddress());
+        // siaddr
+        bos.write(SERVER_ADDR.getAddress());
+        // giaddr
+        bos.write(INADDR_ANY.getAddress());
+        // chaddr
+        bos.write(CLIENT_MAC);
+
+        // Padding
+        bos.write(new byte[202]);
+
+        // Options
+        bos.write(new byte[]{
+                // Magic cookie 0x63825363.
+                (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
+                // Message type OFFER.
+                (byte) 0x35, (byte) 0x01, (byte) 0x02,
+        });
+        // Server ID
+        bos.write(new byte[] { (byte) 0x36, (byte) 0x04 });
+        bos.write(SERVER_ADDR.getAddress());
+        // Lease time
+        bos.write(new byte[] { (byte) 0x33, (byte) 0x04 });
+        bos.write(intToByteArray(leaseTimeSecs));
+        if (leaseTimeSecs != INFINITE_LEASE) {
+            // Renewal time
+            bos.write(new byte[]{(byte) 0x3a, (byte) 0x04});
+            bos.write(intToByteArray(renewalTime));
+            // Rebinding time
+            bos.write(new byte[]{(byte) 0x3b, (byte) 0x04});
+            bos.write(intToByteArray(rebindingTime));
+        }
+        // Subnet mask
+        bos.write(new byte[] { (byte) 0x01, (byte) 0x04 });
+        bos.write(NETMASK.getAddress());
+        // Broadcast address
+        bos.write(new byte[] { (byte) 0x1c, (byte) 0x04 });
+        bos.write(BROADCAST_ADDR.getAddress());
+        // Router
+        bos.write(new byte[] { (byte) 0x03, (byte) 0x04 });
+        bos.write(SERVER_ADDR.getAddress());
+        // Nameserver
+        bos.write(new byte[] { (byte) 0x06, (byte) 0x04 });
+        bos.write(SERVER_ADDR.getAddress());
+        // Hostname
+        if (hostname != null) {
+            bos.write(new byte[]{(byte) 0x0c, (byte) hostname.length()});
+            bos.write(hostname.getBytes(Charset.forName("US-ASCII")));
+        }
+        // MTU
+        bos.write(new byte[] { (byte) 0x1a, (byte) 0x02 });
+        bos.write(shortToByteArray(MTU));
+        // End options.
+        bos.write(0xff);
+
+        if ((bos.size() & 1) != 0) {
+            bos.write(0x00);
+        }
+
+        final byte[] expected = bos.toByteArray();
+        final byte[] actual = new byte[packet.limit()];
+        packet.get(actual);
+        final String msg = "Expected:\n  " + HexDump.dumpHexString(expected) +
+                "\nActual:\n  " + HexDump.dumpHexString(actual);
+        assertTrue(msg, Arrays.equals(expected, actual));
+    }
+
+    @Test
+    public void testOfferPacket() throws Exception {
+        checkBuildOfferPacket(3600, HOSTNAME);
+        checkBuildOfferPacket(Integer.MAX_VALUE, HOSTNAME);
+        checkBuildOfferPacket(0x80000000, HOSTNAME);
+        checkBuildOfferPacket(INFINITE_LEASE, HOSTNAME);
+        checkBuildOfferPacket(3600, null);
+    }
+
+    private static byte[] intToByteArray(int val) {
+        return ByteBuffer.allocate(4).putInt(val).array();
+    }
+
+    private static byte[] shortToByteArray(short val) {
+        return ByteBuffer.allocate(2).putShort(val).array();
+    }
+}
diff --git a/tests/src/android/net/ip/IpClientTest.java b/tests/src/android/net/ip/IpClientTest.java
new file mode 100644
index 0000000..f21809f
--- /dev/null
+++ b/tests/src/android/net/ip/IpClientTest.java
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2017 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.ip;
+
+import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.INetd;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.MacAddress;
+import android.net.RouteInfo;
+import android.net.shared.InitialConfiguration;
+import android.net.shared.ProvisioningConfiguration;
+import android.net.util.InterfaceParams;
+import android.os.INetworkManagementService;
+import android.provider.Settings;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+
+import com.android.internal.R;
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.net.BaseNetworkObserver;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Tests for IpClient.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpClientTest {
+    private static final int DEFAULT_AVOIDBADWIFI_CONFIG_VALUE = 1;
+
+    private static final String VALID = "VALID";
+    private static final String INVALID = "INVALID";
+    private static final String TEST_IFNAME = "test_wlan0";
+    private static final int TEST_IFINDEX = 1001;
+    // See RFC 7042#section-2.1.2 for EUI-48 documentation values.
+    private static final MacAddress TEST_MAC = MacAddress.fromString("00:00:5E:00:53:01");
+    private static final int TEST_TIMEOUT_MS = 400;
+
+    @Mock private Context mContext;
+    @Mock private ConnectivityManager mCm;
+    @Mock private INetworkManagementService mNMService;
+    @Mock private INetd mNetd;
+    @Mock private Resources mResources;
+    @Mock private IIpClientCallbacks mCb;
+    @Mock private AlarmManager mAlarm;
+    @Mock private IpClient.Dependencies mDependecies;
+    private MockContentResolver mContentResolver;
+
+    private BaseNetworkObserver mObserver;
+    private InterfaceParams mIfParams;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm);
+        when(mContext.getSystemServiceName(ConnectivityManager.class))
+                .thenReturn(Context.CONNECTIVITY_SERVICE);
+        when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mCm);
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getInteger(R.integer.config_networkAvoidBadWifi))
+                .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE);
+
+        mContentResolver = new MockContentResolver();
+        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
+
+        mIfParams = null;
+
+        when(mDependecies.getNMS()).thenReturn(mNMService);
+        when(mDependecies.getNetd()).thenReturn(mNetd);
+    }
+
+    private void setTestInterfaceParams(String ifname) {
+        mIfParams = (ifname != null)
+                ? new InterfaceParams(ifname, TEST_IFINDEX, TEST_MAC)
+                : null;
+        when(mDependecies.getInterfaceParams(anyString())).thenReturn(mIfParams);
+    }
+
+    private IpClient makeIpClient(String ifname) throws Exception {
+        setTestInterfaceParams(ifname);
+        final IpClient ipc = new IpClient(mContext, ifname, mCb, mDependecies);
+        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(ifname, false);
+        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(ifname);
+        ArgumentCaptor<BaseNetworkObserver> arg =
+                ArgumentCaptor.forClass(BaseNetworkObserver.class);
+        verify(mNMService, times(1)).registerObserver(arg.capture());
+        mObserver = arg.getValue();
+        reset(mNMService);
+        reset(mNetd);
+        // Verify IpClient doesn't call onLinkPropertiesChange() when it starts.
+        verify(mCb, never()).onLinkPropertiesChange(any());
+        reset(mCb);
+        return ipc;
+    }
+
+    private static LinkProperties makeEmptyLinkProperties(String iface) {
+        final LinkProperties empty = new LinkProperties();
+        empty.setInterfaceName(iface);
+        return empty;
+    }
+
+    @Test
+    public void testNullInterfaceNameMostDefinitelyThrows() throws Exception {
+        setTestInterfaceParams(null);
+        try {
+            final IpClient ipc = new IpClient(mContext, null, mCb, mDependecies);
+            ipc.shutdown();
+            fail();
+        } catch (NullPointerException npe) {
+            // Phew; null interface names not allowed.
+        }
+    }
+
+    @Test
+    public void testNullCallbackMostDefinitelyThrows() throws Exception {
+        final String ifname = "lo";
+        setTestInterfaceParams(ifname);
+        try {
+            final IpClient ipc = new IpClient(mContext, ifname, null, mDependecies);
+            ipc.shutdown();
+            fail();
+        } catch (NullPointerException npe) {
+            // Phew; null callbacks not allowed.
+        }
+    }
+
+    @Test
+    public void testInvalidInterfaceDoesNotThrow() throws Exception {
+        setTestInterfaceParams(TEST_IFNAME);
+        final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mDependecies);
+        ipc.shutdown();
+    }
+
+    @Test
+    public void testInterfaceNotFoundFailsImmediately() throws Exception {
+        setTestInterfaceParams(null);
+        final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mDependecies);
+        ipc.startProvisioning(new ProvisioningConfiguration());
+        verify(mCb, times(1)).onProvisioningFailure(any());
+        ipc.shutdown();
+    }
+
+    @Test
+    public void testDefaultProvisioningConfiguration() throws Exception {
+        final String iface = TEST_IFNAME;
+        final IpClient ipc = makeIpClient(iface);
+
+        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
+                .withoutIPv4()
+                // TODO: mock IpReachabilityMonitor's dependencies (NetworkInterface, PowerManager)
+                // and enable it in this test
+                .withoutIpReachabilityMonitor()
+                .build();
+
+        ipc.startProvisioning(config);
+        verify(mCb, times(1)).setNeighborDiscoveryOffload(true);
+        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false);
+        verify(mCb, never()).onProvisioningFailure(any());
+
+        ipc.shutdown();
+        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
+        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
+        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
+                .onLinkPropertiesChange(argThat(
+                        lp -> fromStableParcelable(lp).equals(makeEmptyLinkProperties(iface))));
+    }
+
+    @Test
+    public void testProvisioningWithInitialConfiguration() throws Exception {
+        final String iface = TEST_IFNAME;
+        final IpClient ipc = makeIpClient(iface);
+
+        String[] addresses = {
+            "fe80::a4be:f92:e1f7:22d1/64",
+            "fe80::f04a:8f6:6a32:d756/64",
+            "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"
+        };
+        String[] prefixes = { "fe80::/64", "fd2c:4e57:8e3c::/64" };
+
+        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
+                .withoutIPv4()
+                .withoutIpReachabilityMonitor()
+                .withInitialConfiguration(conf(links(addresses), prefixes(prefixes), ips()))
+                .build();
+
+        ipc.startProvisioning(config);
+        verify(mCb, times(1)).setNeighborDiscoveryOffload(true);
+        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false);
+        verify(mCb, never()).onProvisioningFailure(any());
+
+        for (String addr : addresses) {
+            String[] parts = addr.split("/");
+            verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1))
+                    .interfaceAddAddress(iface, parts[0], Integer.parseInt(parts[1]));
+        }
+
+        final int lastAddr = addresses.length - 1;
+
+        // Add N - 1 addresses
+        for (int i = 0; i < lastAddr; i++) {
+            mObserver.addressUpdated(iface, new LinkAddress(addresses[i]));
+            verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(any());
+            reset(mCb);
+        }
+
+        // Add Nth address
+        mObserver.addressUpdated(iface, new LinkAddress(addresses[lastAddr]));
+        LinkProperties want = linkproperties(links(addresses), routes(prefixes));
+        want.setInterfaceName(iface);
+        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(argThat(
+                lp -> fromStableParcelable(lp).equals(want)));
+
+        ipc.shutdown();
+        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
+        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
+        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
+                .onLinkPropertiesChange(argThat(
+                        lp -> fromStableParcelable(lp).equals(makeEmptyLinkProperties(iface))));
+    }
+
+    @Test
+    public void testIsProvisioned() throws Exception {
+        InitialConfiguration empty = conf(links(), prefixes());
+        IsProvisionedTestCase[] testcases = {
+            // nothing
+            notProvisionedCase(links(), routes(), dns(), null),
+            notProvisionedCase(links(), routes(), dns(), empty),
+
+            // IPv4
+            provisionedCase(links("192.0.2.12/24"), routes(), dns(), empty),
+
+            // IPv6
+            notProvisionedCase(
+                    links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
+                    routes(), dns(), empty),
+            notProvisionedCase(
+                    links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
+                    routes("fe80::/64", "fd2c:4e57:8e3c::/64"), dns("fd00:1234:5678::1000"), empty),
+            provisionedCase(
+                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
+                    routes("::/0"),
+                    dns("2001:db8:dead:beef:f00::02"), empty),
+
+            // Initial configuration
+            provisionedCase(
+                    links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
+                    routes("fe80::/64", "fd2c:4e57:8e3c::/64"),
+                    dns(),
+                    conf(links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
+                        prefixes( "fe80::/64", "fd2c:4e57:8e3c::/64"), ips()))
+        };
+
+        for (IsProvisionedTestCase testcase : testcases) {
+            if (IpClient.isProvisioned(testcase.lp, testcase.config) != testcase.isProvisioned) {
+                fail(testcase.errorMessage());
+            }
+        }
+    }
+
+    static class IsProvisionedTestCase {
+        boolean isProvisioned;
+        LinkProperties lp;
+        InitialConfiguration config;
+
+        String errorMessage() {
+            return String.format("expected %s with config %s to be %s, but was %s",
+                     lp, config, provisioned(isProvisioned), provisioned(!isProvisioned));
+        }
+
+        static String provisioned(boolean isProvisioned) {
+            return isProvisioned ? "provisioned" : "not provisioned";
+        }
+    }
+
+    static IsProvisionedTestCase provisionedCase(Set<LinkAddress> lpAddrs, Set<RouteInfo> lpRoutes,
+            Set<InetAddress> lpDns, InitialConfiguration config) {
+        return provisioningTest(true, lpAddrs, lpRoutes, lpDns, config);
+    }
+
+    static IsProvisionedTestCase notProvisionedCase(Set<LinkAddress> lpAddrs,
+            Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) {
+        return provisioningTest(false, lpAddrs, lpRoutes, lpDns, config);
+    }
+
+    static IsProvisionedTestCase provisioningTest(boolean isProvisioned, Set<LinkAddress> lpAddrs,
+            Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) {
+        IsProvisionedTestCase testcase = new IsProvisionedTestCase();
+        testcase.isProvisioned = isProvisioned;
+        testcase.lp = new LinkProperties();
+        testcase.lp.setLinkAddresses(lpAddrs);
+        for (RouteInfo route : lpRoutes) {
+            testcase.lp.addRoute(route);
+        }
+        for (InetAddress dns : lpDns) {
+            testcase.lp.addDnsServer(dns);
+        }
+        testcase.config = config;
+        return testcase;
+    }
+
+    @Test
+    public void testInitialConfigurations() throws Exception {
+        InitialConfigurationTestCase[] testcases = {
+            validConf("valid IPv4 configuration",
+                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("192.0.2.2")),
+            validConf("another valid IPv4 configuration",
+                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns()),
+            validConf("valid IPv6 configurations",
+                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
+                    prefixes("2001:db8:dead:beef::/64", "fe80::/64"),
+                    dns("2001:db8:dead:beef:f00::02")),
+            validConf("valid IPv6 configurations",
+                    links("fe80::1/64"), prefixes("fe80::/64"), dns()),
+            validConf("valid IPv6/v4 configuration",
+                    links("2001:db8:dead:beef:f00::a0/48", "192.0.2.12/24"),
+                    prefixes("2001:db8:dead:beef::/64", "192.0.2.0/24"),
+                    dns("192.0.2.2", "2001:db8:dead:beef:f00::02")),
+            validConf("valid IPv6 configuration without any GUA.",
+                    links("fd00:1234:5678::1/48"),
+                    prefixes("fd00:1234:5678::/48"),
+                    dns("fd00:1234:5678::1000")),
+
+            invalidConf("empty configuration", links(), prefixes(), dns()),
+            invalidConf("v4 addr and dns not in any prefix",
+                    links("192.0.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")),
+            invalidConf("v4 addr not in any prefix",
+                    links("198.51.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")),
+            invalidConf("v4 dns addr not in any prefix",
+                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("198.51.100.2")),
+            invalidConf("v6 addr not in any prefix",
+                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
+                    prefixes("2001:db8:dead:beef::/64"),
+                    dns("2001:db8:dead:beef:f00::02")),
+            invalidConf("v6 dns addr not in any prefix",
+                    links("fe80::1/64"), prefixes("fe80::/64"), dns("2001:db8:dead:beef:f00::02")),
+            invalidConf("default ipv6 route and no GUA",
+                    links("fd01:1111:2222:3333::a0/128"), prefixes("::/0"), dns()),
+            invalidConf("invalid v6 prefix length",
+                    links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/32"),
+                    dns()),
+            invalidConf("another invalid v6 prefix length",
+                    links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/72"),
+                    dns())
+        };
+
+        for (InitialConfigurationTestCase testcase : testcases) {
+            if (testcase.config.isValid() != testcase.isValid) {
+                fail(testcase.errorMessage());
+            }
+        }
+    }
+
+    static class InitialConfigurationTestCase {
+        String descr;
+        boolean isValid;
+        InitialConfiguration config;
+        public String errorMessage() {
+            return String.format("%s: expected configuration %s to be %s, but was %s",
+                    descr, config, validString(isValid), validString(!isValid));
+        }
+        static String validString(boolean isValid) {
+            return isValid ? VALID : INVALID;
+        }
+    }
+
+    static InitialConfigurationTestCase validConf(String descr, Set<LinkAddress> links,
+            Set<IpPrefix> prefixes, Set<InetAddress> dns) {
+        return confTestCase(descr, true, conf(links, prefixes, dns));
+    }
+
+    static InitialConfigurationTestCase invalidConf(String descr, Set<LinkAddress> links,
+            Set<IpPrefix> prefixes, Set<InetAddress> dns) {
+        return confTestCase(descr, false, conf(links, prefixes, dns));
+    }
+
+    static InitialConfigurationTestCase confTestCase(
+            String descr, boolean isValid, InitialConfiguration config) {
+        InitialConfigurationTestCase testcase = new InitialConfigurationTestCase();
+        testcase.descr = descr;
+        testcase.isValid = isValid;
+        testcase.config = config;
+        return testcase;
+    }
+
+    static LinkProperties linkproperties(Set<LinkAddress> addresses, Set<RouteInfo> routes) {
+        LinkProperties lp = new LinkProperties();
+        lp.setLinkAddresses(addresses);
+        for (RouteInfo route : routes) {
+            lp.addRoute(route);
+        }
+        return lp;
+    }
+
+    static InitialConfiguration conf(Set<LinkAddress> links, Set<IpPrefix> prefixes) {
+        return conf(links, prefixes, new HashSet<>());
+    }
+
+    static InitialConfiguration conf(
+            Set<LinkAddress> links, Set<IpPrefix> prefixes, Set<InetAddress> dns) {
+        InitialConfiguration conf = new InitialConfiguration();
+        conf.ipAddresses.addAll(links);
+        conf.directlyConnectedRoutes.addAll(prefixes);
+        conf.dnsServers.addAll(dns);
+        return conf;
+    }
+
+    static Set<RouteInfo> routes(String... routes) {
+        return mapIntoSet(routes, (r) -> new RouteInfo(new IpPrefix(r)));
+    }
+
+    static Set<IpPrefix> prefixes(String... prefixes) {
+        return mapIntoSet(prefixes, IpPrefix::new);
+    }
+
+    static Set<LinkAddress> links(String... addresses) {
+        return mapIntoSet(addresses, LinkAddress::new);
+    }
+
+    static Set<InetAddress> ips(String... addresses) {
+        return mapIntoSet(addresses, InetAddress::getByName);
+    }
+
+    static Set<InetAddress> dns(String... addresses) {
+        return ips(addresses);
+    }
+
+    static <A, B> Set<B> mapIntoSet(A[] in, Fn<A, B> fn) {
+        Set<B> out = new HashSet<>(in.length);
+        for (A item : in) {
+            try {
+                out.add(fn.call(item));
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+        return out;
+    }
+
+    interface Fn<A,B> {
+        B call(A a) throws Exception;
+    }
+
+    @Test
+    public void testAll() {
+        List<String> list1 = Arrays.asList();
+        List<String> list2 = Arrays.asList("foo");
+        List<String> list3 = Arrays.asList("bar", "baz");
+        List<String> list4 = Arrays.asList("foo", "bar", "baz");
+
+        assertTrue(InitialConfiguration.all(list1, (x) -> false));
+        assertFalse(InitialConfiguration.all(list2, (x) -> false));
+        assertTrue(InitialConfiguration.all(list3, (x) -> true));
+        assertTrue(InitialConfiguration.all(list2, (x) -> x.charAt(0) == 'f'));
+        assertFalse(InitialConfiguration.all(list4, (x) -> x.charAt(0) == 'f'));
+    }
+
+    @Test
+    public void testAny() {
+        List<String> list1 = Arrays.asList();
+        List<String> list2 = Arrays.asList("foo");
+        List<String> list3 = Arrays.asList("bar", "baz");
+        List<String> list4 = Arrays.asList("foo", "bar", "baz");
+
+        assertFalse(InitialConfiguration.any(list1, (x) -> true));
+        assertTrue(InitialConfiguration.any(list2, (x) -> true));
+        assertTrue(InitialConfiguration.any(list2, (x) -> x.charAt(0) == 'f'));
+        assertFalse(InitialConfiguration.any(list3, (x) -> x.charAt(0) == 'f'));
+        assertTrue(InitialConfiguration.any(list4, (x) -> x.charAt(0) == 'f'));
+    }
+
+    @Test
+    public void testFindAll() {
+        List<String> list1 = Arrays.asList();
+        List<String> list2 = Arrays.asList("foo");
+        List<String> list3 = Arrays.asList("foo", "bar", "baz");
+
+        assertEquals(list1, IpClient.findAll(list1, (x) -> true));
+        assertEquals(list1, IpClient.findAll(list3, (x) -> false));
+        assertEquals(list3, IpClient.findAll(list3, (x) -> true));
+        assertEquals(list2, IpClient.findAll(list3, (x) -> x.charAt(0) == 'f'));
+    }
+}
diff --git a/tests/src/android/net/ip/IpReachabilityMonitorTest.java b/tests/src/android/net/ip/IpReachabilityMonitorTest.java
new file mode 100644
index 0000000..e3b5ddf
--- /dev/null
+++ b/tests/src/android/net/ip/IpReachabilityMonitorTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 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.ip;
+
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.util.InterfaceParams;
+import android.net.util.SharedLog;
+import android.os.Handler;
+import android.os.Looper;
+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;
+
+
+/**
+ * Tests for IpReachabilityMonitor.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpReachabilityMonitorTest {
+
+    @Mock IpReachabilityMonitor.Callback mCallback;
+    @Mock IpReachabilityMonitor.Dependencies mDependencies;
+    @Mock SharedLog mLog;
+    @Mock Context mContext;
+    Handler mHandler;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mLog.forSubComponent(anyString())).thenReturn(mLog);
+        mHandler = new Handler(Looper.getMainLooper());
+    }
+
+    IpReachabilityMonitor makeMonitor() {
+        final InterfaceParams ifParams = new InterfaceParams("fake0", 1, null);
+        return new IpReachabilityMonitor(
+                mContext, ifParams, mHandler, mLog, mCallback, false, mDependencies);
+    }
+
+    @Test
+    public void testNothing() {
+        IpReachabilityMonitor monitor = makeMonitor();
+    }
+}
diff --git a/tests/src/android/net/util/ConnectivityPacketSummaryTest.java b/tests/src/android/net/util/ConnectivityPacketSummaryTest.java
new file mode 100644
index 0000000..dfaf52a
--- /dev/null
+++ b/tests/src/android/net/util/ConnectivityPacketSummaryTest.java
@@ -0,0 +1,418 @@
+/*
+ * 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 org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.net.MacAddress;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import libcore.util.HexEncoding;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for ConnectivityPacketSummary.
+ *
+ * @hide
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConnectivityPacketSummaryTest {
+    private static final MacAddress MYHWADDR = MacAddress.fromString("80:7a:bf:6f:48:f3");
+
+    private String getSummary(String hexBytes) {
+        hexBytes = hexBytes.replaceAll("\\s+", "");
+        final byte[] bytes = HexEncoding.decode(hexBytes.toCharArray(), false);
+        return ConnectivityPacketSummary.summarize(MYHWADDR, bytes);
+    }
+
+    @Test
+    public void testParseICMPv6DADProbe() {
+        final String packet =
+                // Ethernet
+                "3333FF6F48F3 807ABF6F48F3 86DD" +
+                // IPv6
+                "600000000018 3A FF" +
+                "00000000000000000000000000000000" +
+                "FF0200000000000000000001FF6F48F3" +
+                // ICMPv6
+                "87 00 A8E7" +
+                "00000000" +
+                "FE80000000000000827ABFFFFE6F48F3";
+
+        final String expected =
+                "TX 80:7a:bf:6f:48:f3 > 33:33:ff:6f:48:f3 ipv6" +
+                " :: > ff02::1:ff6f:48f3 icmp6" +
+                " ns fe80::827a:bfff:fe6f:48f3";
+
+        assertEquals(expected, getSummary(packet));
+    }
+
+    @Test
+    public void testParseICMPv6RS() {
+        final String packet =
+                // Ethernet
+                "333300000002 807ABF6F48F3 86DD" +
+                // IPv6
+                "600000000010 3A FF" +
+                "FE80000000000000827ABFFFFE6F48F3" +
+                "FF020000000000000000000000000002" +
+                // ICMPv6 RS
+                "85 00 6973" +
+                "00000000" +
+                "01 01 807ABF6F48F3";
+
+        final String expected =
+                "TX 80:7a:bf:6f:48:f3 > 33:33:00:00:00:02 ipv6" +
+                " fe80::827a:bfff:fe6f:48f3 > ff02::2 icmp6" +
+                " rs slla 80:7a:bf:6f:48:f3";
+
+        assertEquals(expected, getSummary(packet));
+    }
+
+    @Test
+    public void testParseICMPv6RA() {
+        final String packet =
+                // Ethernet
+                "807ABF6F48F3 100E7E263FC1 86DD" +
+                // IPv6
+                "600000000068 3A FF" +
+                "FE80000000000000FA000004FD000001" +
+                "FE80000000000000827ABFFFFE6F48F3" +
+                // ICMPv6 RA
+                "86 00 8141" +
+                "40 00 0E10" +
+                "00000000" +
+                "00000000" +
+                "01 01 00005E000265" +
+                "05 01 0000000005DC" +
+                "19 05 000000000E10" +
+                "      20014860486000000000000000008844" +
+                "      20014860486000000000000000008888" +
+                "03 04 40 C0" +
+                "      00278D00" +
+                "      00093A80" +
+                "      00000000" +
+                "      2401FA000004FD000000000000000000";
+
+        final String expected =
+                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
+                " fe80::fa00:4:fd00:1 > fe80::827a:bfff:fe6f:48f3 icmp6" +
+                " ra slla 00:00:5e:00:02:65 mtu 1500";
+
+        assertEquals(expected, getSummary(packet));
+    }
+
+    @Test
+    public void testParseICMPv6NS() {
+        final String packet =
+                // Ethernet
+                  "807ABF6F48F3 100E7E263FC1 86DD" +
+                  // IPv6
+                  "6C0000000020 3A FF" +
+                  "FE80000000000000FA000004FD000001" +
+                  "FF0200000000000000000001FF01C146" +
+                  // ICMPv6 NS
+                  "87 00 8AD4" +
+                  "00000000" +
+                  "2401FA000004FD0015EA6A5C7B01C146" +
+                  "01 01 00005E000265";
+
+        final String expected =
+                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
+                " fe80::fa00:4:fd00:1 > ff02::1:ff01:c146 icmp6" +
+                " ns 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 slla 00:00:5e:00:02:65";
+
+        assertEquals(expected, getSummary(packet));
+    }
+
+    @Test
+    public void testInvalidICMPv6NDLength() {
+        final String packet =
+                // Ethernet
+                "807ABF6F48F3 100E7E263FC1 86DD" +
+                // IPv6
+                "600000000068 3A FF" +
+                "FE80000000000000FA000004FD000001" +
+                "FE80000000000000827ABFFFFE6F48F3" +
+                // ICMPv6 RA
+                "86 00 8141" +
+                "40 00 0E10" +
+                "00000000" +
+                "00000000" +
+                "01 01 00005E000265" +
+                "00 00 0102030405D6";
+
+        final String expected =
+                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
+                " fe80::fa00:4:fd00:1 > fe80::827a:bfff:fe6f:48f3 icmp6" +
+                " ra slla 00:00:5e:00:02:65 <malformed>";
+
+        assertEquals(expected, getSummary(packet));
+    }
+
+    @Test
+    public void testParseICMPv6NA() {
+        final String packet =
+                // Ethernet
+                "00005E000265 807ABF6F48F3 86DD" +
+                "600000000020 3A FF" +
+                "2401FA000004FD0015EA6A5C7B01C146" +
+                "FE80000000000000FA000004FD000001" +
+                "88 00 E8126" +
+                "0000000" +
+                "2401FA000004FD0015EA6A5C7B01C146" +
+                "02 01 807ABF6F48F3";
+
+        final String expected =
+                "TX 80:7a:bf:6f:48:f3 > 00:00:5e:00:02:65 ipv6" +
+                " 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 > fe80::fa00:4:fd00:1 icmp6" +
+                " na 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 tlla 80:7a:bf:6f:48:f3";
+
+        assertEquals(expected, getSummary(packet));
+    }
+
+    @Test
+    public void testParseARPRequest() {
+        final String packet =
+                // Ethernet
+                  "FFFFFFFFFFFF 807ABF6F48F3 0806" +
+                  // ARP
+                  "0001 0800 06 04" +
+                  // Request
+                  "0001" +
+                  "807ABF6F48F3 64706ADB" +
+                  "000000000000 64706FFD";
+
+        final String expected =
+                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff arp" +
+                " who-has 100.112.111.253";
+
+        assertEquals(expected, getSummary(packet));
+    }
+
+    @Test
+    public void testParseARPReply() {
+        final String packet =
+                // Ethernet
+                  "807ABF6F48F3 288A1CA8DFC1 0806" +
+                  // ARP
+                  "0001 0800 06 04" +
+                  // Reply
+                  "0002" +
+                  "288A1CA8DFC1 64706FFD"+
+                  "807ABF6F48F3 64706ADB" +
+                  // Ethernet padding to packet min size.
+                  "0000000000000000000000000000";
+
+        final String expected =
+                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 arp" +
+                " reply 100.112.111.253 28:8a:1c:a8:df:c1";
+
+        assertEquals(expected, getSummary(packet));
+    }
+
+    @Test
+    public void testParseDHCPv4Discover() {
+        final String packet =
+                // Ethernet
+                "FFFFFFFFFFFF 807ABF6F48F3 0800" +
+                // IPv4
+                "451001580000400040113986" +
+                "00000000" +
+                "FFFFFFFF" +
+                // UDP
+                "0044 0043" +
+                "0144 5559" +
+                // DHCPv4
+                "01 01 06 00" +
+                "79F7ACA4" +
+                "0000 0000" +
+                "00000000" +
+                "00000000" +
+                "00000000" +
+                "00000000" +
+                "807ABF6F48F300000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "63 82 53 63" +
+                "35 01 01" +
+                "3D 07 01807ABF6F48F3" +
+                "39 02 05DC" +
+                "3C 12 616E64726F69642D646863702D372E312E32" +
+                "0C 18 616E64726F69642D36623030366333313333393835343139" +
+                "37 0A 01 03 06 0F 1A 1C 33 3A 3B 2B" +
+                "FF" +
+                "00";
+
+        final String expectedPrefix =
+                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff ipv4" +
+                " 0.0.0.0 > 255.255.255.255 udp" +
+                " 68 > 67 dhcp4" +
+                " 80:7a:bf:6f:48:f3 DISCOVER";
+
+        assertTrue(getSummary(packet).startsWith(expectedPrefix));
+    }
+
+    @Test
+    public void testParseDHCPv4Offer() {
+        final String packet =
+                // Ethernet
+                "807ABF6F48F3 288A1CA8DFC1 0800" +
+                // IPv4
+                "4500013D4D2C0000401188CB" +
+                "64706FFD" +
+                "64706ADB" +
+                // UDP
+                "0043 0044" +
+                "0129 371D" +
+                // DHCPv4
+                "02 01 06 01" +
+                "79F7ACA4" +
+                "0000 0000" +
+                "00000000" +
+                "64706ADB" +
+                "00000000" +
+                "00000000" +
+                "807ABF6F48F300000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "63 82 53 63" +
+                "35 01 02" +
+                "36 04 AC188A0B" +
+                "33 04 00000708" +
+                "01 04 FFFFF000" +
+                "03 04 64706FFE" +
+                "06 08 08080808" +
+                "      08080404" +
+                "FF0001076165313A363636FF";
+
+        final String expectedPrefix =
+                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 ipv4" +
+                " 100.112.111.253 > 100.112.106.219 udp" +
+                " 67 > 68 dhcp4" +
+                " 80:7a:bf:6f:48:f3 OFFER";
+
+        assertTrue(getSummary(packet).startsWith(expectedPrefix));
+    }
+
+    @Test
+    public void testParseDHCPv4Request() {
+        final String packet =
+                // Ethernet
+                "FFFFFFFFFFFF 807ABF6F48F3 0800" +
+                // IPv4
+                "45100164000040004011397A" +
+                "00000000" +
+                "FFFFFFFF" +
+                // UDP
+                "0044 0043" +
+                "0150 E5C7" +
+                // DHCPv4
+                "01 01 06 00" +
+                "79F7ACA4" +
+                "0001 0000" +
+                "00000000" +
+                "00000000" +
+                "00000000" +
+                "00000000" +
+                "807ABF6F48F300000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "63 82 53 63" +
+                "35 01 03" +
+                "3D 07 01807ABF6F48F3" +
+                "32 04 64706ADB" +
+                "36 04 AC188A0B" +
+                "39 02 05DC" +
+                "3C 12 616E64726F69642D646863702D372E312E32" +
+                "0C 18 616E64726F69642D36623030366333313333393835343139" +
+                "37 0A 01 03 06 0F 1A 1C 33 3A 3B 2B" +
+                "FF" +
+                "00";
+
+        final String expectedPrefix =
+                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff ipv4" +
+                " 0.0.0.0 > 255.255.255.255 udp" +
+                " 68 > 67 dhcp4" +
+                " 80:7a:bf:6f:48:f3 REQUEST";
+
+        assertTrue(getSummary(packet).startsWith(expectedPrefix));
+    }
+
+    @Test
+    public void testParseDHCPv4Ack() {
+        final String packet =
+                // Ethernet
+                "807ABF6F48F3 288A1CA8DFC1 0800" +
+                // IPv4
+                "4500013D4D3B0000401188BC" +
+                "64706FFD" +
+                "64706ADB" +
+                // UDP
+                "0043 0044" +
+                "0129 341C" +
+                // DHCPv4
+                "02 01 06 01" +
+                "79F7ACA4" +
+                "0001 0000" +
+                "00000000" +
+                "64706ADB" +
+                "00000000" +
+                "00000000" +
+                "807ABF6F48F300000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "0000000000000000000000000000000000000000000000000000000000000000" +
+                "63 82 53 63" +
+                "35 01 05" +
+                "36 04 AC188A0B" +
+                "33 04 00000708" +
+                "01 04 FFFFF000" +
+                "03 04 64706FFE" +
+                "06 08 08080808" +
+                "      08080404" +
+                "FF0001076165313A363636FF";
+
+        final String expectedPrefix =
+                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 ipv4" +
+                " 100.112.111.253 > 100.112.106.219 udp" +
+                " 67 > 68 dhcp4" +
+                " 80:7a:bf:6f:48:f3 ACK";
+
+        assertTrue(getSummary(packet).startsWith(expectedPrefix));
+    }
+}
diff --git a/tests/src/android/net/util/PacketReaderTest.java b/tests/src/android/net/util/PacketReaderTest.java
new file mode 100644
index 0000000..dced743
--- /dev/null
+++ b/tests/src/android/net/util/PacketReaderTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.net.util.PacketReader.DEFAULT_RECV_BUF_SIZE;
+import static android.system.OsConstants.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructTimeval;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketException;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.runner.RunWith;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import libcore.io.IoBridge;
+
+/**
+ * Tests for PacketReader.
+ *
+ * @hide
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class PacketReaderTest {
+    static final InetAddress LOOPBACK6 = Inet6Address.getLoopbackAddress();
+    static final StructTimeval TIMEO = StructTimeval.fromMillis(500);
+
+    protected CountDownLatch mLatch;
+    protected FileDescriptor mLocalSocket;
+    protected InetSocketAddress mLocalSockName;
+    protected byte[] mLastRecvBuf;
+    protected boolean mStopped;
+    protected HandlerThread mHandlerThread;
+    protected PacketReader mReceiver;
+
+    class UdpLoopbackReader extends PacketReader {
+        public UdpLoopbackReader(Handler h) {
+            super(h);
+        }
+
+        @Override
+        protected FileDescriptor createFd() {
+            FileDescriptor s = null;
+            try {
+                s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+                Os.bind(s, LOOPBACK6, 0);
+                mLocalSockName = (InetSocketAddress) Os.getsockname(s);
+                Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO);
+            } catch (ErrnoException|SocketException e) {
+                closeFd(s);
+                fail();
+                return null;
+            }
+
+            mLocalSocket = s;
+            return s;
+        }
+
+        @Override
+        protected void handlePacket(byte[] recvbuf, int length) {
+            mLastRecvBuf = Arrays.copyOf(recvbuf, length);
+            mLatch.countDown();
+        }
+
+        @Override
+        protected void onStart() {
+            mStopped = false;
+            mLatch.countDown();
+        }
+
+        @Override
+        protected void onStop() {
+            mStopped = true;
+            mLatch.countDown();
+        }
+    };
+
+    @Before
+    public void setUp() {
+        resetLatch();
+        mLocalSocket = null;
+        mLocalSockName = null;
+        mLastRecvBuf = null;
+        mStopped = false;
+
+        mHandlerThread = new HandlerThread(PacketReaderTest.class.getSimpleName());
+        mHandlerThread.start();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mReceiver != null) {
+            mHandlerThread.getThreadHandler().post(() -> { mReceiver.stop(); });
+            waitForActivity();
+        }
+        mReceiver = null;
+        mHandlerThread.quit();
+        mHandlerThread = null;
+    }
+
+    void resetLatch() { mLatch = new CountDownLatch(1); }
+
+    void waitForActivity() throws Exception {
+        try {
+            mLatch.await(1000, TimeUnit.MILLISECONDS);
+        } finally {
+            resetLatch();
+        }
+    }
+
+    void sendPacket(byte[] contents) throws Exception {
+        final DatagramSocket sender = new DatagramSocket();
+        sender.connect(mLocalSockName);
+        sender.send(new DatagramPacket(contents, contents.length));
+        sender.close();
+    }
+
+    @Test
+    public void testBasicWorking() throws Exception {
+        final Handler h = mHandlerThread.getThreadHandler();
+        mReceiver = new UdpLoopbackReader(h);
+
+        h.post(() -> { mReceiver.start(); });
+        waitForActivity();
+        assertTrue(mLocalSockName != null);
+        assertEquals(LOOPBACK6, mLocalSockName.getAddress());
+        assertTrue(0 < mLocalSockName.getPort());
+        assertTrue(mLocalSocket != null);
+        assertFalse(mStopped);
+
+        final byte[] one = "one 1".getBytes("UTF-8");
+        sendPacket(one);
+        waitForActivity();
+        assertEquals(1, mReceiver.numPacketsReceived());
+        assertTrue(Arrays.equals(one, mLastRecvBuf));
+        assertFalse(mStopped);
+
+        final byte[] two = "two 2".getBytes("UTF-8");
+        sendPacket(two);
+        waitForActivity();
+        assertEquals(2, mReceiver.numPacketsReceived());
+        assertTrue(Arrays.equals(two, mLastRecvBuf));
+        assertFalse(mStopped);
+
+        mReceiver.stop();
+        waitForActivity();
+        assertEquals(2, mReceiver.numPacketsReceived());
+        assertTrue(Arrays.equals(two, mLastRecvBuf));
+        assertTrue(mStopped);
+        mReceiver = null;
+    }
+
+    class NullPacketReader extends PacketReader {
+        public NullPacketReader(Handler h, int recvbufsize) {
+            super(h, recvbufsize);
+        }
+
+        @Override
+        public FileDescriptor createFd() { return null; }
+    }
+
+    @Test
+    public void testMinimalRecvBufSize() throws Exception {
+        final Handler h = mHandlerThread.getThreadHandler();
+
+        for (int i : new int[]{-1, 0, 1, DEFAULT_RECV_BUF_SIZE-1}) {
+            final PacketReader b = new NullPacketReader(h, i);
+            assertEquals(DEFAULT_RECV_BUF_SIZE, b.recvBufSize());
+        }
+    }
+}
