diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index 2f7d599..a2da0a0 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -24,7 +24,7 @@
         ":services-networkstack-shared-srcs",
     ],
     static_libs: [
-        "dhcp-packet-lib",
+        "services-netlink-lib",
     ]
 }
 
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
index 7f8bb93..5ab833b 100644
--- a/packages/NetworkStack/AndroidManifest.xml
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
new file mode 100644
index 0000000..50c4dfc
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/apf/ApfGenerator.java b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
new file mode 100644
index 0000000..87a1b5e
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java
new file mode 100644
index 0000000..b2eb4e2
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
new file mode 100644
index 0000000..04ac9a3
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java
new file mode 100644
index 0000000..7ecdea7
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java
new file mode 100644
index 0000000..11f2b61
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java
new file mode 100644
index 0000000..7a83466
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java
new file mode 100644
index 0000000..1da0b73
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java
new file mode 100644
index 0000000..0eba77e
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
new file mode 100644
index 0000000..ce8b7e7
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java
new file mode 100644
index 0000000..3958303
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java
new file mode 100644
index 0000000..231d0457
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java b/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
new file mode 100644
index 0000000..385dd52
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
new file mode 100644
index 0000000..ad7f85d
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java b/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
new file mode 100644
index 0000000..eb993a4
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
new file mode 100644
index 0000000..761db68
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java b/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java
new file mode 100644
index 0000000..08c3f60
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/util/FdEventsReader.java b/packages/NetworkStack/src/android/net/util/FdEventsReader.java
new file mode 100644
index 0000000..8bbf449
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/android/net/util/PacketReader.java b/packages/NetworkStack/src/android/net/util/PacketReader.java
new file mode 100644
index 0000000..4aec6b6
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
index cca71e7..4080ddf 100644
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ b/packages/NetworkStack/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/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java b/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java
index bb5900c..eedaf30 100644
--- a/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp
index bd7ff2a..45fa2dc 100644
--- a/packages/NetworkStack/tests/Android.bp
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/AndroidManifest.xml b/packages/NetworkStack/tests/AndroidManifest.xml
index 8b8474f..9cb2c21 100644
--- a/packages/NetworkStack/tests/AndroidManifest.xml
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/jni/apf_jni.cpp b/packages/NetworkStack/tests/jni/apf_jni.cpp
new file mode 100644
index 0000000..4222adf
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/res/raw/apf.pcap b/packages/NetworkStack/tests/res/raw/apf.pcap
new file mode 100644
index 0000000..963165f
--- /dev/null
+++ b/packages/NetworkStack/tests/res/raw/apf.pcap
Binary files differ
diff --git a/packages/NetworkStack/tests/res/raw/apfPcap.pcap b/packages/NetworkStack/tests/res/raw/apfPcap.pcap
new file mode 100644
index 0000000..6f69c4a
--- /dev/null
+++ b/packages/NetworkStack/tests/res/raw/apfPcap.pcap
Binary files differ
diff --git a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
new file mode 100644
index 0000000..f76e412
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/src/android/net/apf/Bpf2Apf.java b/packages/NetworkStack/tests/src/android/net/apf/Bpf2Apf.java
new file mode 100644
index 0000000..5d57cde
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java b/packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java
new file mode 100644
index 0000000..a592809
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java b/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java
new file mode 100644
index 0000000..f21809f
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/src/android/net/ip/IpReachabilityMonitorTest.java b/packages/NetworkStack/tests/src/android/net/ip/IpReachabilityMonitorTest.java
new file mode 100644
index 0000000..e3b5ddf
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/src/android/net/util/ConnectivityPacketSummaryTest.java b/packages/NetworkStack/tests/src/android/net/util/ConnectivityPacketSummaryTest.java
new file mode 100644
index 0000000..dfaf52a
--- /dev/null
+++ b/packages/NetworkStack/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/packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java b/packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java
new file mode 100644
index 0000000..dced743
--- /dev/null
+++ b/packages/NetworkStack/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());
+        }
+    }
+}
