diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 81939a5..9c6e16f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -113,6 +113,7 @@
 import com.android.internal.util.XmlUtils;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.connectivity.DataConnectionStats;
+import com.android.server.connectivity.NetworkDiagnostics;
 import com.android.server.connectivity.Nat464Xlat;
 import com.android.server.connectivity.NetworkAgentInfo;
 import com.android.server.connectivity.NetworkMonitor;
@@ -1752,6 +1753,15 @@
         return ret;
     }
 
+    private boolean shouldPerformDiagnostics(String[] args) {
+        for (String arg : args) {
+            if (arg.equals("--diag")) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
@@ -1764,6 +1774,26 @@
             return;
         }
 
+        final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
+        if (shouldPerformDiagnostics(args)) {
+            final long DIAG_TIME_MS = 5000;
+            for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
+                // Start gathering diagnostic information.
+                netDiags.add(new NetworkDiagnostics(
+                        nai.network,
+                        new LinkProperties(nai.linkProperties),
+                        DIAG_TIME_MS));
+            }
+
+            for (NetworkDiagnostics netDiag : netDiags) {
+                pw.println();
+                netDiag.waitForMeasurements();
+                netDiag.dump(pw);
+            }
+
+            return;
+        }
+
         pw.print("NetworkFactories for:");
         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
             pw.print(" " + nfi.name);
@@ -2000,20 +2030,22 @@
                     break;
                 }
                 case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: {
+                    final int netId = msg.arg2;
                     if (msg.arg1 == 0) {
-                        setProvNotificationVisibleIntent(false, msg.arg2, 0, null, null);
+                        setProvNotificationVisibleIntent(false, netId, null, 0, null, null);
                     } else {
                         final NetworkAgentInfo nai;
                         synchronized (mNetworkForNetId) {
-                            nai = mNetworkForNetId.get(msg.arg2);
+                            nai = mNetworkForNetId.get(netId);
                         }
                         if (nai == null) {
                             loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
                             break;
                         }
                         nai.captivePortalDetected = true;
-                        setProvNotificationVisibleIntent(true, msg.arg2, nai.networkInfo.getType(),
-                                nai.networkInfo.getExtraInfo(), (PendingIntent)msg.obj);
+                        setProvNotificationVisibleIntent(true, netId, NotificationType.SIGN_IN,
+                                nai.networkInfo.getType(),nai.networkInfo.getExtraInfo(),
+                                (PendingIntent)msg.obj);
                     }
                     break;
                 }
@@ -2370,9 +2402,7 @@
         }
 
         if (nai.everValidated) {
-            // The network validated while the dialog box was up. Don't make any changes. There's a
-            // TODO in the dialog code to make it go away if the network validates; once that's
-            // implemented, taking action here will be confusing.
+            // The network validated while the dialog box was up. Take no action.
             return;
         }
 
@@ -2392,16 +2422,28 @@
                     NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, accept ? 1 : 0);
         }
 
-        // TODO: should we also disconnect from the network if accept is false?
+        if (!accept) {
+            // Tell the NetworkAgent that the network does not have Internet access (because that's
+            // what we just told the user). This will hint to Wi-Fi not to autojoin this network in
+            // the future. We do this now because NetworkMonitor might not yet have finished
+            // validating and thus we might not yet have received an EVENT_NETWORK_TESTED.
+            nai.asyncChannel.sendMessage(NetworkAgent.CMD_REPORT_NETWORK_STATUS,
+                    NetworkAgent.INVALID_NETWORK, 0, null);
+            // TODO: Tear the network down once we have determined how to tell WifiStateMachine not
+            // to reconnect to it immediately. http://b/20739299
+        }
+
     }
 
     private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) {
+        if (DBG) log("scheduleUnvalidatedPrompt " + nai.network);
         mHandler.sendMessageDelayed(
                 mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network),
                 PROMPT_UNVALIDATED_DELAY_MS);
     }
 
     private void handlePromptUnvalidated(Network network) {
+        if (DBG) log("handlePromptUnvalidated " + network);
         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
 
         // Only prompt if the network is unvalidated and was explicitly selected by the user, and if
@@ -2412,31 +2454,16 @@
             return;
         }
 
-        // TODO: What should we do if we've already switched to this network because we had no
-        // better option? There are two obvious alternatives.
-        //
-        // 1. Decide that there's no point prompting because this is our only usable network.
-        //    However, because we didn't prompt, if later on a validated network comes along, we'll
-        //    either a) silently switch to it - bad if the user wanted to connect to stay on this
-        //    unvalidated network - or b) prompt the user at that later time - bad because the user
-        //    might not understand why they are now being prompted.
-        //
-        // 2. Always prompt the user, even if we have no other network to use. The user could then
-        //    try to find an alternative network to join (remember, if we got here, then the user
-        //    selected this network manually). This is bad because the prompt isn't really very
-        //    useful.
-        //
-        // For now we do #1, but we can revisit that later.
-        if (isDefaultNetwork(nai)) {
-            return;
-        }
-
         Intent intent = new Intent(ConnectivityManager.ACTION_PROMPT_UNVALIDATED);
-        intent.putExtra(ConnectivityManager.EXTRA_NETWORK, network);
+        intent.setData(Uri.fromParts("netId", Integer.toString(network.netId), null));
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.setClassName("com.android.settings",
                 "com.android.settings.wifi.WifiNoInternetDialog");
-        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+
+        PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
+                mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+        setProvNotificationVisibleIntent(true, nai.network.netId, NotificationType.NO_INTERNET,
+                nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(), pendingIntent);
     }
 
     private class InternalHandler extends Handler {
@@ -2997,7 +3024,12 @@
         throwIfLockdownEnabled();
 
         synchronized(mVpns) {
-            return mVpns.get(userId).prepare(oldPackage, newPackage);
+            Vpn vpn = mVpns.get(userId);
+            if (vpn != null) {
+                return vpn.prepare(oldPackage, newPackage);
+            } else {
+                return false;
+            }
         }
     }
 
@@ -3019,7 +3051,10 @@
         enforceCrossUserPermission(userId);
 
         synchronized(mVpns) {
-            mVpns.get(userId).setPackageAuthorization(packageName, authorized);
+            Vpn vpn = mVpns.get(userId);
+            if (vpn != null) {
+                vpn.setPackageAuthorization(packageName, authorized);
+            }
         }
     }
 
@@ -3130,7 +3165,12 @@
     public VpnConfig getVpnConfig(int userId) {
         enforceCrossUserPermission(userId);
         synchronized(mVpns) {
-            return mVpns.get(userId).getVpnConfig();
+            Vpn vpn = mVpns.get(userId);
+            if (vpn != null) {
+                return vpn.getVpnConfig();
+            } else {
+                return null;
+            }
         }
     }
 
@@ -3203,7 +3243,7 @@
     }
 
     private static final String NOTIFICATION_ID = "CaptivePortal.Notification";
-    private volatile boolean mIsNotificationVisible = false;
+    private static enum NotificationType { SIGN_IN, NO_INTERNET; };
 
     private void setProvNotificationVisible(boolean visible, int networkType, String action) {
         if (DBG) {
@@ -3214,21 +3254,31 @@
         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
         // Concatenate the range of types onto the range of NetIDs.
         int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
-        setProvNotificationVisibleIntent(visible, id, networkType, null, pendingIntent);
+        setProvNotificationVisibleIntent(visible, id, NotificationType.SIGN_IN,
+                networkType, null, pendingIntent);
     }
 
     /**
-     * Show or hide network provisioning notificaitons.
+     * Show or hide network provisioning notifications.
+     *
+     * We use notifications for two purposes: to notify that a network requires sign in
+     * (NotificationType.SIGN_IN), or to notify that a network does not have Internet access
+     * (NotificationType.NO_INTERNET). We display at most one notification per ID, so on a
+     * particular network we can display the notification type that was most recently requested.
+     * So for example if a captive portal fails to reply within a few seconds of connecting, we
+     * might first display NO_INTERNET, and then when the captive portal check completes, display
+     * SIGN_IN.
      *
      * @param id an identifier that uniquely identifies this notification.  This must match
      *         between show and hide calls.  We use the NetID value but for legacy callers
      *         we concatenate the range of types with the range of NetIDs.
      */
-    private void setProvNotificationVisibleIntent(boolean visible, int id, int networkType,
-            String extraInfo, PendingIntent intent) {
+    private void setProvNotificationVisibleIntent(boolean visible, int id,
+            NotificationType notifyType, int networkType, String extraInfo, PendingIntent intent) {
         if (DBG) {
-            log("setProvNotificationVisibleIntent: E visible=" + visible + " networkType=" +
-                networkType + " extraInfo=" + extraInfo);
+            log("setProvNotificationVisibleIntent " + notifyType + " visible=" + visible
+                    + " networkType=" + getNetworkTypeName(networkType)
+                    + " extraInfo=" + extraInfo);
         }
 
         Resources r = Resources.getSystem();
@@ -3240,27 +3290,38 @@
             CharSequence details;
             int icon;
             Notification notification = new Notification();
-            switch (networkType) {
-                case ConnectivityManager.TYPE_WIFI:
-                    title = r.getString(R.string.wifi_available_sign_in, 0);
-                    details = r.getString(R.string.network_available_sign_in_detailed,
-                            extraInfo);
-                    icon = R.drawable.stat_notify_wifi_in_range;
-                    break;
-                case ConnectivityManager.TYPE_MOBILE:
-                case ConnectivityManager.TYPE_MOBILE_HIPRI:
-                    title = r.getString(R.string.network_available_sign_in, 0);
-                    // TODO: Change this to pull from NetworkInfo once a printable
-                    // name has been added to it
-                    details = mTelephonyManager.getNetworkOperatorName();
-                    icon = R.drawable.stat_notify_rssi_in_range;
-                    break;
-                default:
-                    title = r.getString(R.string.network_available_sign_in, 0);
-                    details = r.getString(R.string.network_available_sign_in_detailed,
-                            extraInfo);
-                    icon = R.drawable.stat_notify_rssi_in_range;
-                    break;
+            if (notifyType == NotificationType.NO_INTERNET &&
+                    networkType == ConnectivityManager.TYPE_WIFI) {
+                title = r.getString(R.string.wifi_no_internet, 0);
+                details = r.getString(R.string.wifi_no_internet_detailed);
+                icon = R.drawable.stat_notify_wifi_in_range;  // TODO: Need new icon.
+            } else if (notifyType == NotificationType.SIGN_IN) {
+                switch (networkType) {
+                    case ConnectivityManager.TYPE_WIFI:
+                        title = r.getString(R.string.wifi_available_sign_in, 0);
+                        details = r.getString(R.string.network_available_sign_in_detailed,
+                                extraInfo);
+                        icon = R.drawable.stat_notify_wifi_in_range;
+                        break;
+                    case ConnectivityManager.TYPE_MOBILE:
+                    case ConnectivityManager.TYPE_MOBILE_HIPRI:
+                        title = r.getString(R.string.network_available_sign_in, 0);
+                        // TODO: Change this to pull from NetworkInfo once a printable
+                        // name has been added to it
+                        details = mTelephonyManager.getNetworkOperatorName();
+                        icon = R.drawable.stat_notify_rssi_in_range;
+                        break;
+                    default:
+                        title = r.getString(R.string.network_available_sign_in, 0);
+                        details = r.getString(R.string.network_available_sign_in_detailed,
+                                extraInfo);
+                        icon = R.drawable.stat_notify_rssi_in_range;
+                        break;
+                }
+            } else {
+                Slog.wtf(TAG, "Unknown notification type " + notifyType + "on network type "
+                        + getNetworkTypeName(networkType));
+                return;
             }
 
             notification.when = 0;
@@ -3275,18 +3336,17 @@
             try {
                 notificationManager.notify(NOTIFICATION_ID, id, notification);
             } catch (NullPointerException npe) {
-                loge("setNotificaitionVisible: visible notificationManager npe=" + npe);
+                loge("setNotificationVisible: visible notificationManager npe=" + npe);
                 npe.printStackTrace();
             }
         } else {
             try {
                 notificationManager.cancel(NOTIFICATION_ID, id);
             } catch (NullPointerException npe) {
-                loge("setNotificaitionVisible: cancel notificationManager npe=" + npe);
+                loge("setNotificationVisible: cancel notificationManager npe=" + npe);
                 npe.printStackTrace();
             }
         }
-        mIsNotificationVisible = visible;
     }
 
     /** Location to an updatable file listing carrier provisioning urls.
diff --git a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
new file mode 100644
index 0000000..5d56d4a
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
@@ -0,0 +1,509 @@
+/*
+ * 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 com.android.server.connectivity;
+
+import static android.system.OsConstants.*;
+
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.RouteInfo;
+import android.os.SystemClock;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructTimeval;
+import android.text.TextUtils;
+
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import libcore.io.IoUtils;
+
+
+/**
+ * NetworkDiagnostics
+ *
+ * A simple class to diagnose network connectivity fundamentals.  Current
+ * checks performed are:
+ *     - ICMPv4/v6 echo requests for all routers
+ *     - ICMPv4/v6 echo requests for all DNS servers
+ *     - DNS UDP queries to all DNS servers
+ *
+ * Currently unimplemented checks include:
+ *     - report ARP/ND data about on-link neighbors
+ *     - DNS TCP queries to all DNS servers
+ *     - HTTP DIRECT and PROXY checks
+ *     - port 443 blocking/TLS intercept checks
+ *     - QUIC reachability checks
+ *     - MTU checks
+ *
+ * The supplied timeout bounds the entire diagnostic process.  Each specific
+ * check class must implement this upper bound on measurements in whichever
+ * manner is most appropriate and effective.
+ *
+ * @hide
+ */
+public class NetworkDiagnostics {
+    private static final String TAG = "NetworkDiagnostics";
+
+    // For brevity elsewhere.
+    private static final long now() {
+        return SystemClock.elapsedRealtime();
+    }
+
+    // Values from RFC 1035 section 4.1.1, names from <arpa/nameser.h>.
+    // Should be a member of DnsUdpCheck, but "compiler says no".
+    public static enum DnsResponseCode { NOERROR, FORMERR, SERVFAIL, NXDOMAIN, NOTIMP, REFUSED };
+
+    private final Network mNetwork;
+    private final LinkProperties mLinkProperties;
+    private final Integer mInterfaceIndex;
+
+    private final long mTimeoutMs;
+    private final long mStartTime;
+    private final long mDeadlineTime;
+
+    // A counter, initialized to the total number of measurements,
+    // so callers can wait for completion.
+    private final CountDownLatch mCountDownLatch;
+
+    private class Measurement {
+        private static final String SUCCEEDED = "SUCCEEDED";
+        private static final String FAILED = "FAILED";
+
+        // TODO: Refactor to make these private for better encapsulation.
+        public String description = "";
+        public long startTime;
+        public long finishTime;
+        public String result = "";
+        public Thread thread;
+
+        public void recordSuccess(String msg) {
+            maybeFixupTimes();
+            if (mCountDownLatch != null) {
+                mCountDownLatch.countDown();
+            }
+            result = SUCCEEDED + ": " + msg;
+        }
+
+        public void recordFailure(String msg) {
+            maybeFixupTimes();
+            if (mCountDownLatch != null) {
+                mCountDownLatch.countDown();
+            }
+            result = FAILED + ": " + msg;
+        }
+
+        private void maybeFixupTimes() {
+            // Allows the caller to just set success/failure and not worry
+            // about also setting the correct finishing time.
+            if (finishTime == 0) { finishTime = now(); }
+
+            // In cases where, for example, a failure has occurred before the
+            // measurement even began, fixup the start time to reflect as much.
+            if (startTime == 0) { startTime = finishTime; }
+        }
+
+        @Override
+        public String toString() {
+            return description + ": " + result + " (" + (finishTime - startTime) + "ms)";
+        }
+    }
+
+    private final Map<InetAddress, Measurement> mIcmpChecks = new HashMap<>();
+    private final Map<InetAddress, Measurement> mDnsUdpChecks = new HashMap<>();
+    private final String mDescription;
+
+
+    public NetworkDiagnostics(Network network, LinkProperties lp, long timeoutMs) {
+        mNetwork = network;
+        mLinkProperties = lp;
+        mInterfaceIndex = getInterfaceIndex(mLinkProperties.getInterfaceName());
+        mTimeoutMs = timeoutMs;
+        mStartTime = now();
+        mDeadlineTime = mStartTime + mTimeoutMs;
+
+        for (RouteInfo route : mLinkProperties.getRoutes()) {
+            if (route.hasGateway()) {
+                prepareIcmpMeasurement(route.getGateway());
+            }
+        }
+        for (InetAddress nameserver : mLinkProperties.getDnsServers()) {
+                prepareIcmpMeasurement(nameserver);
+                prepareDnsMeasurement(nameserver);
+        }
+
+        mCountDownLatch = new CountDownLatch(totalMeasurementCount());
+
+        startMeasurements();
+
+        mDescription = "ifaces{" + TextUtils.join(",", mLinkProperties.getAllInterfaceNames()) + "}"
+                + " index{" + mInterfaceIndex + "}"
+                + " network{" + mNetwork + "}"
+                + " nethandle{" + mNetwork.getNetworkHandle() + "}";
+    }
+
+    private static Integer getInterfaceIndex(String ifname) {
+        try {
+            NetworkInterface ni = NetworkInterface.getByName(ifname);
+            return ni.getIndex();
+        } catch (NullPointerException | SocketException e) {
+            return null;
+        }
+    }
+
+    private void prepareIcmpMeasurement(InetAddress target) {
+        if (!mIcmpChecks.containsKey(target)) {
+            Measurement measurement = new Measurement();
+            measurement.thread = new Thread(new IcmpCheck(target, measurement));
+            mIcmpChecks.put(target, measurement);
+        }
+    }
+
+    private void prepareDnsMeasurement(InetAddress target) {
+        if (!mDnsUdpChecks.containsKey(target)) {
+            Measurement measurement = new Measurement();
+            measurement.thread = new Thread(new DnsUdpCheck(target, measurement));
+            mDnsUdpChecks.put(target, measurement);
+        }
+    }
+
+    private int totalMeasurementCount() {
+        return mIcmpChecks.size() + mDnsUdpChecks.size();
+    }
+
+    private void startMeasurements() {
+        for (Measurement measurement : mIcmpChecks.values()) {
+            measurement.thread.start();
+        }
+        for (Measurement measurement : mDnsUdpChecks.values()) {
+            measurement.thread.start();
+        }
+    }
+
+    public void waitForMeasurements() {
+        try {
+            mCountDownLatch.await(mDeadlineTime - now(), TimeUnit.MILLISECONDS);
+        } catch (InterruptedException ignored) {}
+    }
+
+    public void dump(IndentingPrintWriter pw) {
+        pw.println(TAG + ":" + mDescription);
+        final long unfinished = mCountDownLatch.getCount();
+        if (unfinished > 0) {
+            // This can't happen unless a caller forgets to call waitForMeasurements()
+            // or a measurement isn't implemented to correctly honor the timeout.
+            pw.println("WARNING: countdown wait incomplete: "
+                    + unfinished + " unfinished measurements");
+        }
+
+        pw.increaseIndent();
+        for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
+            if (entry.getKey() instanceof Inet4Address) {
+                pw.println(entry.getValue().toString());
+            }
+        }
+        for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
+            if (entry.getKey() instanceof Inet6Address) {
+                pw.println(entry.getValue().toString());
+            }
+        }
+        for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
+            if (entry.getKey() instanceof Inet4Address) {
+                pw.println(entry.getValue().toString());
+            }
+        }
+        for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
+            if (entry.getKey() instanceof Inet6Address) {
+                pw.println(entry.getValue().toString());
+            }
+        }
+        pw.decreaseIndent();
+    }
+
+
+    private class SimpleSocketCheck implements Closeable {
+        protected final InetAddress mTarget;
+        protected final int mAddressFamily;
+        protected final Measurement mMeasurement;
+        protected FileDescriptor mFileDescriptor;
+        protected SocketAddress mSocketAddress;
+
+        protected SimpleSocketCheck(InetAddress target, Measurement measurement) {
+            mMeasurement = measurement;
+
+            if (target instanceof Inet6Address) {
+                Inet6Address targetWithScopeId = null;
+                if (target.isLinkLocalAddress() && mInterfaceIndex != null) {
+                    try {
+                        targetWithScopeId = Inet6Address.getByAddress(
+                                null, target.getAddress(), mInterfaceIndex);
+                    } catch (UnknownHostException e) {
+                        mMeasurement.recordFailure(e.toString());
+                    }
+                }
+                mTarget = (targetWithScopeId != null) ? targetWithScopeId : target;
+                mAddressFamily = AF_INET6;
+            } else {
+                mTarget = target;
+                mAddressFamily = AF_INET;
+            }
+        }
+
+        protected void setupSocket(
+                int sockType, int protocol, long writeTimeout, long readTimeout, int dstPort)
+                throws ErrnoException, IOException {
+            mFileDescriptor = Os.socket(mAddressFamily, sockType, protocol);
+            // Setting SNDTIMEO is purely for defensive purposes.
+            Os.setsockoptTimeval(mFileDescriptor,
+                    SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(writeTimeout));
+            Os.setsockoptTimeval(mFileDescriptor,
+                    SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(readTimeout));
+            // TODO: Use IP_RECVERR/IPV6_RECVERR, pending OsContants availability.
+            mNetwork.bindSocket(mFileDescriptor);
+            Os.connect(mFileDescriptor, mTarget, dstPort);
+            mSocketAddress = Os.getsockname(mFileDescriptor);
+        }
+
+        protected String getSocketAddressString() {
+            // The default toString() implementation is not the prettiest.
+            InetSocketAddress inetSockAddr = (InetSocketAddress) mSocketAddress;
+            InetAddress localAddr = inetSockAddr.getAddress();
+            return String.format(
+                    (localAddr instanceof Inet6Address ? "[%s]:%d" : "%s:%d"),
+                    localAddr.getHostAddress(), inetSockAddr.getPort());
+        }
+
+        @Override
+        public void close() {
+            IoUtils.closeQuietly(mFileDescriptor);
+        }
+    }
+
+
+    private class IcmpCheck extends SimpleSocketCheck implements Runnable {
+        private static final int TIMEOUT_SEND = 100;
+        private static final int TIMEOUT_RECV = 300;
+        private static final int ICMPV4_ECHO_REQUEST = 8;
+        private static final int ICMPV6_ECHO_REQUEST = 128;
+        private static final int PACKET_BUFSIZE = 512;
+        private final int mProtocol;
+        private final int mIcmpType;
+
+        public IcmpCheck(InetAddress target, Measurement measurement) {
+            super(target, measurement);
+
+            if (mAddressFamily == AF_INET6) {
+                mProtocol = IPPROTO_ICMPV6;
+                mIcmpType = ICMPV6_ECHO_REQUEST;
+                mMeasurement.description = "ICMPv6";
+            } else {
+                mProtocol = IPPROTO_ICMP;
+                mIcmpType = ICMPV4_ECHO_REQUEST;
+                mMeasurement.description = "ICMPv4";
+            }
+
+            mMeasurement.description += " dst{" + mTarget.getHostAddress() + "}";
+        }
+
+        @Override
+        public void run() {
+            // Check if this measurement has already failed during setup.
+            if (mMeasurement.finishTime > 0) {
+                // If the measurement failed during construction it didn't
+                // decrement the countdown latch; do so here.
+                mCountDownLatch.countDown();
+                return;
+            }
+
+            try {
+                setupSocket(SOCK_DGRAM, mProtocol, TIMEOUT_SEND, TIMEOUT_RECV, 0);
+            } catch (ErrnoException | IOException e) {
+                mMeasurement.recordFailure(e.toString());
+                return;
+            }
+            mMeasurement.description += " src{" + getSocketAddressString() + "}";
+
+            // Build a trivial ICMP packet.
+            final byte[] icmpPacket = {
+                    (byte) mIcmpType, 0, 0, 0, 0, 0, 0, 0  // ICMP header
+            };
+
+            int count = 0;
+            mMeasurement.startTime = now();
+            while (now() < mDeadlineTime - (TIMEOUT_SEND + TIMEOUT_RECV)) {
+                count++;
+                icmpPacket[icmpPacket.length - 1] = (byte) count;
+                try {
+                    Os.write(mFileDescriptor, icmpPacket, 0, icmpPacket.length);
+                } catch (ErrnoException | InterruptedIOException e) {
+                    mMeasurement.recordFailure(e.toString());
+                    break;
+                }
+
+                try {
+                    ByteBuffer reply = ByteBuffer.allocate(PACKET_BUFSIZE);
+                    Os.read(mFileDescriptor, reply);
+                    // TODO: send a few pings back to back to guesstimate packet loss.
+                    mMeasurement.recordSuccess("1/" + count);
+                    break;
+                } catch (ErrnoException | InterruptedIOException e) {
+                    continue;
+                }
+            }
+            if (mMeasurement.finishTime == 0) {
+                mMeasurement.recordFailure("0/" + count);
+            }
+
+            close();
+        }
+    }
+
+
+    private class DnsUdpCheck extends SimpleSocketCheck implements Runnable {
+        private static final int TIMEOUT_SEND = 100;
+        private static final int TIMEOUT_RECV = 500;
+        private static final int DNS_SERVER_PORT = 53;
+        private static final int RR_TYPE_A = 1;
+        private static final int RR_TYPE_AAAA = 28;
+        private static final int PACKET_BUFSIZE = 512;
+
+        private final Random mRandom = new Random();
+
+        // Should be static, but the compiler mocks our puny, human attempts at reason.
+        private String responseCodeStr(int rcode) {
+            try {
+                return DnsResponseCode.values()[rcode].toString();
+            } catch (IndexOutOfBoundsException e) {
+                return String.valueOf(rcode);
+            }
+        }
+
+        private final int mQueryType;
+
+        public DnsUdpCheck(InetAddress target, Measurement measurement) {
+            super(target, measurement);
+
+            // TODO: Ideally, query the target for both types regardless of address family.
+            if (mAddressFamily == AF_INET6) {
+                mQueryType = RR_TYPE_AAAA;
+            } else {
+                mQueryType = RR_TYPE_A;
+            }
+
+            mMeasurement.description = "DNS UDP dst{" + mTarget.getHostAddress() + "}";
+        }
+
+        @Override
+        public void run() {
+            // Check if this measurement has already failed during setup.
+            if (mMeasurement.finishTime > 0) {
+                // If the measurement failed during construction it didn't
+                // decrement the countdown latch; do so here.
+                mCountDownLatch.countDown();
+                return;
+            }
+
+            try {
+                setupSocket(SOCK_DGRAM, IPPROTO_UDP, TIMEOUT_SEND, TIMEOUT_RECV, DNS_SERVER_PORT);
+            } catch (ErrnoException | IOException e) {
+                mMeasurement.recordFailure(e.toString());
+                return;
+            }
+            mMeasurement.description += " src{" + getSocketAddressString() + "}";
+
+            // This needs to be fixed length so it can be dropped into the pre-canned packet.
+            final String sixRandomDigits =
+                    Integer.valueOf(mRandom.nextInt(900000) + 100000).toString();
+            mMeasurement.description += " qtype{" + mQueryType + "}"
+                    + " qname{" + sixRandomDigits + "-android-ds.metric.gstatic.com}";
+
+            // Build a trivial DNS packet.
+            final byte[] dnsPacket = getDnsQueryPacket(sixRandomDigits);
+
+            int count = 0;
+            mMeasurement.startTime = now();
+            while (now() < mDeadlineTime - (TIMEOUT_RECV + TIMEOUT_RECV)) {
+                count++;
+                try {
+                    Os.write(mFileDescriptor, dnsPacket, 0, dnsPacket.length);
+                } catch (ErrnoException | InterruptedIOException e) {
+                    mMeasurement.recordFailure(e.toString());
+                    break;
+                }
+
+                try {
+                    ByteBuffer reply = ByteBuffer.allocate(PACKET_BUFSIZE);
+                    Os.read(mFileDescriptor, reply);
+                    // TODO: more correct and detailed evaluation of the response,
+                    // possibly adding the returned IP address(es) to the output.
+                    final String rcodeStr = (reply.limit() > 3)
+                            ? " " + responseCodeStr((int) (reply.get(3)) & 0x0f)
+                            : "";
+                    mMeasurement.recordSuccess("1/" + count + rcodeStr);
+                    break;
+                } catch (ErrnoException | InterruptedIOException e) {
+                    continue;
+                }
+            }
+            if (mMeasurement.finishTime == 0) {
+                mMeasurement.recordFailure("0/" + count);
+            }
+
+            close();
+        }
+
+        private byte[] getDnsQueryPacket(String sixRandomDigits) {
+            byte[] rnd = sixRandomDigits.getBytes(StandardCharsets.US_ASCII);
+            return new byte[] {
+                (byte) mRandom.nextInt(), (byte) mRandom.nextInt(),  // [0-1]   query ID
+                1, 0,  // [2-3]   flags; byte[2] = 1 for recursion desired (RD).
+                0, 1,  // [4-5]   QDCOUNT (number of queries)
+                0, 0,  // [6-7]   ANCOUNT (number of answers)
+                0, 0,  // [8-9]   NSCOUNT (number of name server records)
+                0, 0,  // [10-11] ARCOUNT (number of additional records)
+                17, rnd[0], rnd[1], rnd[2], rnd[3], rnd[4], rnd[5],
+                        '-', 'a', 'n', 'd', 'r', 'o', 'i', 'd', '-', 'd', 's',
+                6, 'm', 'e', 't', 'r', 'i', 'c',
+                7, 'g', 's', 't', 'a', 't', 'i', 'c',
+                3, 'c', 'o', 'm',
+                0,  // null terminator of FQDN (root TLD)
+                0, (byte) mQueryType,  // QTYPE
+                0, 1  // QCLASS, set to 1 = IN (Internet)
+            };
+        }
+    }
+}
