diff --git a/netd/Android.mk b/netd/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/netd/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/netd/MODULE_LICENSE_APACHE2 b/netd/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/netd/MODULE_LICENSE_APACHE2
diff --git a/netd/NOTICE b/netd/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/netd/NOTICE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/netd/client/Android.mk b/netd/client/Android.mk
new file mode 100644
index 0000000..e202534
--- /dev/null
+++ b/netd/client/Android.mk
@@ -0,0 +1,25 @@
+# Copyright (C) 2014 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES := bionic/libc/dns/include system/netd/include
+LOCAL_CLANG := true
+LOCAL_CPPFLAGS := -std=c++11 -Wall -Werror
+LOCAL_MODULE := libnetd_client
+LOCAL_SRC_FILES := FwmarkClient.cpp NetdClient.cpp
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/netd/client/FwmarkClient.cpp b/netd/client/FwmarkClient.cpp
new file mode 100644
index 0000000..a82f4c2
--- /dev/null
+++ b/netd/client/FwmarkClient.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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 "FwmarkClient.h"
+
+#include "FwmarkCommand.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+namespace {
+
+const sockaddr_un FWMARK_SERVER_PATH = {AF_UNIX, "/dev/socket/fwmarkd"};
+
+}  // namespace
+
+bool FwmarkClient::shouldSetFwmark(int family) {
+    return (family == AF_INET || family == AF_INET6) && !getenv("ANDROID_NO_USE_FWMARK_CLIENT");
+}
+
+FwmarkClient::FwmarkClient() : mChannel(-1) {
+}
+
+FwmarkClient::~FwmarkClient() {
+    if (mChannel >= 0) {
+        close(mChannel);
+    }
+}
+
+int FwmarkClient::send(FwmarkCommand* data, int fd) {
+    mChannel = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+    if (mChannel == -1) {
+        return -errno;
+    }
+
+    if (TEMP_FAILURE_RETRY(connect(mChannel, reinterpret_cast<const sockaddr*>(&FWMARK_SERVER_PATH),
+                                   sizeof(FWMARK_SERVER_PATH))) == -1) {
+        // If we are unable to connect to the fwmark server, assume there's no error. This protects
+        // against future changes if the fwmark server goes away.
+        return 0;
+    }
+
+    iovec iov;
+    iov.iov_base = data;
+    iov.iov_len = sizeof(*data);
+
+    msghdr message;
+    memset(&message, 0, sizeof(message));
+    message.msg_iov = &iov;
+    message.msg_iovlen = 1;
+
+    union {
+        cmsghdr cmh;
+        char cmsg[CMSG_SPACE(sizeof(fd))];
+    } cmsgu;
+
+    if (data->cmdId != FwmarkCommand::QUERY_USER_ACCESS) {
+        memset(cmsgu.cmsg, 0, sizeof(cmsgu.cmsg));
+        message.msg_control = cmsgu.cmsg;
+        message.msg_controllen = sizeof(cmsgu.cmsg);
+
+        cmsghdr* const cmsgh = CMSG_FIRSTHDR(&message);
+        cmsgh->cmsg_len = CMSG_LEN(sizeof(fd));
+        cmsgh->cmsg_level = SOL_SOCKET;
+        cmsgh->cmsg_type = SCM_RIGHTS;
+        memcpy(CMSG_DATA(cmsgh), &fd, sizeof(fd));
+    }
+
+    if (TEMP_FAILURE_RETRY(sendmsg(mChannel, &message, 0)) == -1) {
+        return -errno;
+    }
+
+    int error = 0;
+
+    if (TEMP_FAILURE_RETRY(recv(mChannel, &error, sizeof(error), 0)) == -1) {
+        return -errno;
+    }
+
+    return error;
+}
diff --git a/netd/client/FwmarkClient.h b/netd/client/FwmarkClient.h
new file mode 100644
index 0000000..df7686d
--- /dev/null
+++ b/netd/client/FwmarkClient.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_CLIENT_FWMARK_CLIENT_H
+#define NETD_CLIENT_FWMARK_CLIENT_H
+
+#include <sys/socket.h>
+
+struct FwmarkCommand;
+
+class FwmarkClient {
+public:
+    // Returns true if a socket of the given |family| should be sent to the fwmark server to have
+    // its SO_MARK set.
+    static bool shouldSetFwmark(int family);
+
+    FwmarkClient();
+    ~FwmarkClient();
+
+    // Sends |data| to the fwmark server, along with |fd| as ancillary data using cmsg(3).
+    // Returns 0 on success or a negative errno value on failure.
+    int send(FwmarkCommand* data, int fd);
+
+private:
+    int mChannel;
+};
+
+#endif  // NETD_CLIENT_FWMARK_CLIENT_H
diff --git a/netd/client/NetdClient.cpp b/netd/client/NetdClient.cpp
new file mode 100644
index 0000000..392b0af
--- /dev/null
+++ b/netd/client/NetdClient.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2014 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 "NetdClient.h"
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <atomic>
+
+#include "Fwmark.h"
+#include "FwmarkClient.h"
+#include "FwmarkCommand.h"
+#include "resolv_netid.h"
+
+namespace {
+
+std::atomic_uint netIdForProcess(NETID_UNSET);
+std::atomic_uint netIdForResolv(NETID_UNSET);
+
+typedef int (*Accept4FunctionType)(int, sockaddr*, socklen_t*, int);
+typedef int (*ConnectFunctionType)(int, const sockaddr*, socklen_t);
+typedef int (*SocketFunctionType)(int, int, int);
+typedef unsigned (*NetIdForResolvFunctionType)(unsigned);
+
+// These variables are only modified at startup (when libc.so is loaded) and never afterwards, so
+// it's okay that they are read later at runtime without a lock.
+Accept4FunctionType libcAccept4 = 0;
+ConnectFunctionType libcConnect = 0;
+SocketFunctionType libcSocket = 0;
+
+int closeFdAndSetErrno(int fd, int error) {
+    close(fd);
+    errno = -error;
+    return -1;
+}
+
+int netdClientAccept4(int sockfd, sockaddr* addr, socklen_t* addrlen, int flags) {
+    int acceptedSocket = libcAccept4(sockfd, addr, addrlen, flags);
+    if (acceptedSocket == -1) {
+        return -1;
+    }
+    int family;
+    if (addr) {
+        family = addr->sa_family;
+    } else {
+        socklen_t familyLen = sizeof(family);
+        if (getsockopt(acceptedSocket, SOL_SOCKET, SO_DOMAIN, &family, &familyLen) == -1) {
+            return closeFdAndSetErrno(acceptedSocket, -errno);
+        }
+    }
+    if (FwmarkClient::shouldSetFwmark(family)) {
+        FwmarkCommand command = {FwmarkCommand::ON_ACCEPT, 0, 0};
+        if (int error = FwmarkClient().send(&command, acceptedSocket)) {
+            return closeFdAndSetErrno(acceptedSocket, error);
+        }
+    }
+    return acceptedSocket;
+}
+
+int netdClientConnect(int sockfd, const sockaddr* addr, socklen_t addrlen) {
+    if (sockfd >= 0 && addr && FwmarkClient::shouldSetFwmark(addr->sa_family)) {
+        FwmarkCommand command = {FwmarkCommand::ON_CONNECT, 0, 0};
+        if (int error = FwmarkClient().send(&command, sockfd)) {
+            errno = -error;
+            return -1;
+        }
+    }
+    return libcConnect(sockfd, addr, addrlen);
+}
+
+int netdClientSocket(int domain, int type, int protocol) {
+    int socketFd = libcSocket(domain, type, protocol);
+    if (socketFd == -1) {
+        return -1;
+    }
+    unsigned netId = netIdForProcess;
+    if (netId != NETID_UNSET && FwmarkClient::shouldSetFwmark(domain)) {
+        if (int error = setNetworkForSocket(netId, socketFd)) {
+            return closeFdAndSetErrno(socketFd, error);
+        }
+    }
+    return socketFd;
+}
+
+unsigned getNetworkForResolv(unsigned netId) {
+    if (netId != NETID_UNSET) {
+        return netId;
+    }
+    netId = netIdForProcess;
+    if (netId != NETID_UNSET) {
+        return netId;
+    }
+    return netIdForResolv;
+}
+
+int setNetworkForTarget(unsigned netId, std::atomic_uint* target) {
+    if (netId == NETID_UNSET) {
+        *target = netId;
+        return 0;
+    }
+    // Verify that we are allowed to use |netId|, by creating a socket and trying to have it marked
+    // with the netId. Call libcSocket() directly; else the socket creation (via netdClientSocket())
+    // might itself cause another check with the fwmark server, which would be wasteful.
+    int socketFd;
+    if (libcSocket) {
+        socketFd = libcSocket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    } else {
+        socketFd = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    }
+    if (socketFd < 0) {
+        return -errno;
+    }
+    int error = setNetworkForSocket(netId, socketFd);
+    if (!error) {
+        *target = netId;
+    }
+    close(socketFd);
+    return error;
+}
+
+}  // namespace
+
+// accept() just calls accept4(..., 0), so there's no need to handle accept() separately.
+extern "C" void netdClientInitAccept4(Accept4FunctionType* function) {
+    if (function && *function) {
+        libcAccept4 = *function;
+        *function = netdClientAccept4;
+    }
+}
+
+extern "C" void netdClientInitConnect(ConnectFunctionType* function) {
+    if (function && *function) {
+        libcConnect = *function;
+        *function = netdClientConnect;
+    }
+}
+
+extern "C" void netdClientInitSocket(SocketFunctionType* function) {
+    if (function && *function) {
+        libcSocket = *function;
+        *function = netdClientSocket;
+    }
+}
+
+extern "C" void netdClientInitNetIdForResolv(NetIdForResolvFunctionType* function) {
+    if (function) {
+        *function = getNetworkForResolv;
+    }
+}
+
+extern "C" int getNetworkForSocket(unsigned* netId, int socketFd) {
+    if (!netId || socketFd < 0) {
+        return -EBADF;
+    }
+    Fwmark fwmark;
+    socklen_t fwmarkLen = sizeof(fwmark.intValue);
+    if (getsockopt(socketFd, SOL_SOCKET, SO_MARK, &fwmark.intValue, &fwmarkLen) == -1) {
+        return -errno;
+    }
+    *netId = fwmark.netId;
+    return 0;
+}
+
+extern "C" unsigned getNetworkForProcess() {
+    return netIdForProcess;
+}
+
+extern "C" int setNetworkForSocket(unsigned netId, int socketFd) {
+    if (socketFd < 0) {
+        return -EBADF;
+    }
+    FwmarkCommand command = {FwmarkCommand::SELECT_NETWORK, netId, 0};
+    return FwmarkClient().send(&command, socketFd);
+}
+
+extern "C" int setNetworkForProcess(unsigned netId) {
+    return setNetworkForTarget(netId, &netIdForProcess);
+}
+
+extern "C" int setNetworkForResolv(unsigned netId) {
+    return setNetworkForTarget(netId, &netIdForResolv);
+}
+
+extern "C" int protectFromVpn(int socketFd) {
+    if (socketFd < 0) {
+        return -EBADF;
+    }
+    FwmarkCommand command = {FwmarkCommand::PROTECT_FROM_VPN, 0, 0};
+    return FwmarkClient().send(&command, socketFd);
+}
+
+extern "C" int setNetworkForUser(uid_t uid, int socketFd) {
+    if (socketFd < 0) {
+        return -EBADF;
+    }
+    FwmarkCommand command = {FwmarkCommand::SELECT_FOR_USER, 0, uid};
+    return FwmarkClient().send(&command, socketFd);
+}
+
+extern "C" int queryUserAccess(uid_t uid, unsigned netId) {
+    FwmarkCommand command = {FwmarkCommand::QUERY_USER_ACCESS, netId, uid};
+    return FwmarkClient().send(&command, -1);
+}
diff --git a/netd/include/Fwmark.h b/netd/include/Fwmark.h
new file mode 100644
index 0000000..178e175
--- /dev/null
+++ b/netd/include/Fwmark.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_INCLUDE_FWMARK_H
+#define NETD_INCLUDE_FWMARK_H
+
+#include "Permission.h"
+
+#include <stdint.h>
+
+union Fwmark {
+    uint32_t intValue;
+    struct {
+        unsigned netId          : 16;
+        bool explicitlySelected :  1;
+        bool protectedFromVpn   :  1;
+        Permission permission   :  2;
+    };
+    Fwmark() : intValue(0) {}
+};
+
+static const unsigned FWMARK_NET_ID_MASK = 0xffff;
+
+static_assert(sizeof(Fwmark) == sizeof(uint32_t), "The entire fwmark must fit into 32 bits");
+
+#endif  // NETD_INCLUDE_FWMARK_H
diff --git a/netd/include/FwmarkCommand.h b/netd/include/FwmarkCommand.h
new file mode 100644
index 0000000..be06899
--- /dev/null
+++ b/netd/include/FwmarkCommand.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_INCLUDE_FWMARK_COMMAND_H
+#define NETD_INCLUDE_FWMARK_COMMAND_H
+
+#include <sys/types.h>
+
+// Commands sent from clients to the fwmark server to mark sockets (i.e., set their SO_MARK).
+struct FwmarkCommand {
+    enum {
+        ON_ACCEPT,
+        ON_CONNECT,
+        SELECT_NETWORK,
+        PROTECT_FROM_VPN,
+        SELECT_FOR_USER,
+        QUERY_USER_ACCESS,
+    } cmdId;
+    unsigned netId;  // used only in the SELECT_NETWORK command; ignored otherwise.
+    uid_t uid;  // used only in the SELECT_FOR_USER and QUERY_USER_ACCESS commands;
+                // ignored otherwise.
+};
+
+#endif  // NETD_INCLUDE_FWMARK_COMMAND_H
diff --git a/netd/include/NetdClient.h b/netd/include/NetdClient.h
new file mode 100644
index 0000000..7db0906
--- /dev/null
+++ b/netd/include/NetdClient.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_INCLUDE_NETD_CLIENT_H
+#define NETD_INCLUDE_NETD_CLIENT_H
+
+#include <stdbool.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+// All functions below that return an int return 0 on success or a negative errno value on failure.
+
+int getNetworkForSocket(unsigned* netId, int socketFd);
+int setNetworkForSocket(unsigned netId, int socketFd);
+
+unsigned getNetworkForProcess(void);
+int setNetworkForProcess(unsigned netId);
+
+int setNetworkForResolv(unsigned netId);
+
+int protectFromVpn(int socketFd);
+
+int setNetworkForUser(uid_t uid, int socketFd);
+
+int queryUserAccess(uid_t uid, unsigned netId);
+
+__END_DECLS
+
+#endif  // NETD_INCLUDE_NETD_CLIENT_H
diff --git a/netd/include/Permission.h b/netd/include/Permission.h
new file mode 100644
index 0000000..aa5ae81
--- /dev/null
+++ b/netd/include/Permission.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_INCLUDE_PERMISSION_H
+#define NETD_INCLUDE_PERMISSION_H
+
+// This enum represents the permissions we care about for networking. When applied to an app, it's
+// the permission the app (UID) has been granted. When applied to a network, it's the permission an
+// app must hold to be allowed to use the network. PERMISSION_NONE means "no special permission is
+// held by the app" or "no special permission is required to use the network".
+//
+// Permissions are flags that can be OR'ed together to represent combinations of permissions.
+//
+// PERMISSION_NONE is used for regular networks and apps, such as those that hold the
+// android.permission.INTERNET framework permission.
+//
+// PERMISSION_NETWORK is used for privileged networks and apps that can manipulate or access them,
+// such as those that hold the android.permission.CHANGE_NETWORK_STATE framework permission.
+//
+// PERMISSION_SYSTEM is used for system apps, such as those that are installed on the system
+// partition, those that hold the android.permission.CONNECTIVITY_INTERNAL framework permission and
+// those whose UID is less than FIRST_APPLICATION_UID.
+enum Permission {
+    PERMISSION_NONE    = 0x0,
+    PERMISSION_NETWORK = 0x1,
+    PERMISSION_SYSTEM  = 0x3,  // Includes PERMISSION_NETWORK.
+};
+
+#endif  // NETD_INCLUDE_PERMISSION_H
diff --git a/netd/server/Android.mk b/netd/server/Android.mk
new file mode 100644
index 0000000..1ceda42
--- /dev/null
+++ b/netd/server/Android.mk
@@ -0,0 +1,93 @@
+# Copyright (C) 2014 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES := \
+        $(call include-path-for, libhardware_legacy)/hardware_legacy \
+        bionic/libc/dns/include \
+        external/mdnsresponder/mDNSShared \
+        system/netd/include \
+
+LOCAL_CLANG := true
+LOCAL_CPPFLAGS := -std=c++11 -Wall -Werror
+LOCAL_MODULE := netd
+
+# Bug: http://b/29823425 Disable -Wvarargs for Clang update to r271374
+LOCAL_CPPFLAGS +=  -Wno-varargs
+
+LOCAL_INIT_RC := netd.rc
+
+LOCAL_SHARED_LIBRARIES := \
+        libcrypto \
+        libcutils \
+        libdl \
+        libhardware_legacy \
+        liblog \
+        liblogwrap \
+        libmdnssd \
+        libnetutils \
+        libnl \
+        libsysutils \
+        libbase \
+        libutils \
+
+LOCAL_STATIC_LIBRARIES := \
+        libpcap \
+
+LOCAL_SRC_FILES := \
+        BandwidthController.cpp \
+        ClatdController.cpp \
+        CommandListener.cpp \
+        DnsProxyListener.cpp \
+        DummyNetwork.cpp \
+        FirewallController.cpp \
+        FwmarkServer.cpp \
+        IdletimerController.cpp \
+        InterfaceController.cpp \
+        LocalNetwork.cpp \
+        MDnsSdListener.cpp \
+        NatController.cpp \
+        NetdCommand.cpp \
+        NetdConstants.cpp \
+        NetlinkHandler.cpp \
+        NetlinkManager.cpp \
+        Network.cpp \
+        NetworkController.cpp \
+        PhysicalNetwork.cpp \
+        PppController.cpp \
+        ResolverController.cpp \
+        RouteController.cpp \
+        SockDiag.cpp \
+        SoftapController.cpp \
+        StrictController.cpp \
+        TetherController.cpp \
+        UidRanges.cpp \
+        VirtualNetwork.cpp \
+        main.cpp \
+        oem_iptables_hook.cpp \
+
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -Wall -Werror
+LOCAL_CLANG := true
+LOCAL_MODULE := ndc
+LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_SRC_FILES := ndc.cpp
+
+include $(BUILD_EXECUTABLE)
diff --git a/netd/server/BandwidthController.cpp b/netd/server/BandwidthController.cpp
new file mode 100644
index 0000000..d71ce3b
--- /dev/null
+++ b/netd/server/BandwidthController.cpp
@@ -0,0 +1,1311 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+// #define LOG_NDEBUG 0
+
+/*
+ * The CommandListener, FrameworkListener don't allow for
+ * multiple calls in parallel to reach the BandwidthController.
+ * If they ever were to allow it, then netd/ would need some tweaking.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/pkt_sched.h>
+
+#define LOG_TAG "BandwidthController"
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <logwrap/logwrap.h>
+
+#include "NetdConstants.h"
+#include "BandwidthController.h"
+#include "NatController.h"  /* For LOCAL_TETHER_COUNTERS_CHAIN */
+#include "ResponseCode.h"
+
+/* Alphabetical */
+#define ALERT_IPT_TEMPLATE "%s %s -m quota2 ! --quota %" PRId64" --name %s"
+const char BandwidthController::ALERT_GLOBAL_NAME[] = "globalAlert";
+const char* BandwidthController::LOCAL_INPUT = "bw_INPUT";
+const char* BandwidthController::LOCAL_FORWARD = "bw_FORWARD";
+const char* BandwidthController::LOCAL_OUTPUT = "bw_OUTPUT";
+const char* BandwidthController::LOCAL_RAW_PREROUTING = "bw_raw_PREROUTING";
+const char* BandwidthController::LOCAL_MANGLE_POSTROUTING = "bw_mangle_POSTROUTING";
+const int  BandwidthController::MAX_CMD_ARGS = 32;
+const int  BandwidthController::MAX_CMD_LEN = 1024;
+const int  BandwidthController::MAX_IFACENAME_LEN = 64;
+const int  BandwidthController::MAX_IPT_OUTPUT_LINE_LEN = 256;
+
+/**
+ * Some comments about the rules:
+ *  * Ordering
+ *    - when an interface is marked as costly it should be INSERTED into the INPUT/OUTPUT chains.
+ *      E.g. "-I bw_INPUT -i rmnet0 --jump costly"
+ *    - quota'd rules in the costly chain should be before bw_penalty_box lookups.
+ *    - bw_happy_box rejects everything by default.
+ *    - the qtaguid counting is done at the end of the bw_INPUT/bw_OUTPUT user chains.
+ *
+ * * global quota vs per interface quota
+ *   - global quota for all costly interfaces uses a single costly chain:
+ *    . initial rules
+ *      iptables -N bw_costly_shared
+ *      iptables -I bw_INPUT -i iface0 --jump bw_costly_shared
+ *      iptables -I bw_OUTPUT -o iface0 --jump bw_costly_shared
+ *      iptables -I bw_costly_shared -m quota \! --quota 500000 \
+ *          --jump REJECT --reject-with icmp-net-prohibited
+ *      iptables -A bw_costly_shared --jump bw_penalty_box
+ *      If the happy box is enabled,
+ *        iptables -A bw_penalty_box --jump bw_happy_box
+ *
+ *    . adding a new iface to this, E.g.:
+ *      iptables -I bw_INPUT -i iface1 --jump bw_costly_shared
+ *      iptables -I bw_OUTPUT -o iface1 --jump bw_costly_shared
+ *
+ *   - quota per interface. This is achieve by having "costly" chains per quota.
+ *     E.g. adding a new costly interface iface0 with its own quota:
+ *      iptables -N bw_costly_iface0
+ *      iptables -I bw_INPUT -i iface0 --jump bw_costly_iface0
+ *      iptables -I bw_OUTPUT -o iface0 --jump bw_costly_iface0
+ *      iptables -A bw_costly_iface0 -m quota \! --quota 500000 \
+ *          --jump REJECT --reject-with icmp-port-unreachable
+ *      iptables -A bw_costly_iface0 --jump bw_penalty_box
+ *
+ * * bw_penalty_box handling:
+ *  - only one bw_penalty_box for all interfaces
+ *   E.g  Adding an app, it has to preserve the appened bw_happy_box, so "-I":
+ *    iptables -I bw_penalty_box -m owner --uid-owner app_3 \
+ *        --jump REJECT --reject-with icmp-port-unreachable
+ *
+ * * bw_happy_box handling:
+ *  - The bw_happy_box goes at the end of the penalty box.
+ *   E.g  Adding a happy app,
+ *    iptables -I bw_happy_box -m owner --uid-owner app_3 \
+ *        --jump RETURN
+ */
+const char *BandwidthController::IPT_FLUSH_COMMANDS[] = {
+    /*
+     * Cleanup rules.
+     * Should normally include bw_costly_<iface>, but we rely on the way they are setup
+     * to allow coexistance.
+     */
+    "-F bw_INPUT",
+    "-F bw_OUTPUT",
+    "-F bw_FORWARD",
+    "-F bw_happy_box",
+    "-F bw_penalty_box",
+    "-F bw_costly_shared",
+
+    "-t raw -F bw_raw_PREROUTING",
+    "-t mangle -F bw_mangle_POSTROUTING",
+};
+
+/* The cleanup commands assume flushing has been done. */
+const char *BandwidthController::IPT_CLEANUP_COMMANDS[] = {
+    "-X bw_happy_box",
+    "-X bw_penalty_box",
+    "-X bw_costly_shared",
+};
+
+const char *BandwidthController::IPT_SETUP_COMMANDS[] = {
+    "-N bw_happy_box",
+    "-N bw_penalty_box",
+    "-N bw_costly_shared",
+};
+
+const char *BandwidthController::IPT_BASIC_ACCOUNTING_COMMANDS[] = {
+    "-A bw_INPUT -m owner --socket-exists", /* This is a tracking rule. */
+
+    "-A bw_OUTPUT -m owner --socket-exists", /* This is a tracking rule. */
+
+    "-A bw_costly_shared --jump bw_penalty_box",
+
+    "-t raw -A bw_raw_PREROUTING -m owner --socket-exists", /* This is a tracking rule. */
+    "-t mangle -A bw_mangle_POSTROUTING -m owner --socket-exists", /* This is a tracking rule. */
+};
+
+BandwidthController::BandwidthController(void) {
+}
+
+int BandwidthController::runIpxtablesCmd(const char *cmd, IptJumpOp jumpHandling,
+                                         IptFailureLog failureHandling) {
+    int res = 0;
+
+    ALOGV("runIpxtablesCmd(cmd=%s)", cmd);
+    res |= runIptablesCmd(cmd, jumpHandling, IptIpV4, failureHandling);
+    res |= runIptablesCmd(cmd, jumpHandling, IptIpV6, failureHandling);
+    return res;
+}
+
+int BandwidthController::StrncpyAndCheck(char *buffer, const char *src, size_t buffSize) {
+
+    memset(buffer, '\0', buffSize);  // strncpy() is not filling leftover with '\0'
+    strncpy(buffer, src, buffSize);
+    return buffer[buffSize - 1];
+}
+
+int BandwidthController::runIptablesCmd(const char *cmd, IptJumpOp jumpHandling,
+                                        IptIpVer iptVer, IptFailureLog failureHandling) {
+    char buffer[MAX_CMD_LEN];
+    const char *argv[MAX_CMD_ARGS];
+    int argc = 0;
+    char *next = buffer;
+    char *tmp;
+    int res;
+    int status = 0;
+
+    std::string fullCmd = cmd;
+
+    switch (jumpHandling) {
+    case IptJumpReject:
+        /*
+         * Must be carefull what one rejects with, as uper layer protocols will just
+         * keep on hammering the device until the number of retries are done.
+         * For port-unreachable (default), TCP should consider as an abort (RFC1122).
+         */
+        fullCmd += " --jump REJECT";
+        break;
+    case IptJumpReturn:
+        fullCmd += " --jump RETURN";
+        break;
+    case IptJumpNoAdd:
+        break;
+    }
+
+    fullCmd.insert(0, " -w ");
+    fullCmd.insert(0, iptVer == IptIpV4 ? IPTABLES_PATH : IP6TABLES_PATH);
+
+    if (StrncpyAndCheck(buffer, fullCmd.c_str(), sizeof(buffer))) {
+        ALOGE("iptables command too long");
+        return -1;
+    }
+
+    argc = 0;
+    while ((tmp = strsep(&next, " "))) {
+        argv[argc++] = tmp;
+        if (argc >= MAX_CMD_ARGS) {
+            ALOGE("iptables argument overflow");
+            return -1;
+        }
+    }
+
+    argv[argc] = NULL;
+    res = android_fork_execvp(argc, (char **)argv, &status, false,
+            failureHandling == IptFailShow);
+    res = res || !WIFEXITED(status) || WEXITSTATUS(status);
+    if (res && failureHandling == IptFailShow) {
+      ALOGE("runIptablesCmd(): res=%d status=%d failed %s", res, status,
+            fullCmd.c_str());
+    }
+    return res;
+}
+
+void BandwidthController::flushCleanTables(bool doClean) {
+    /* Flush and remove the bw_costly_<iface> tables */
+    flushExistingCostlyTables(doClean);
+
+    /* Some of the initialCommands are allowed to fail */
+    runCommands(sizeof(IPT_FLUSH_COMMANDS) / sizeof(char*),
+            IPT_FLUSH_COMMANDS, RunCmdFailureOk);
+
+    if (doClean) {
+        runCommands(sizeof(IPT_CLEANUP_COMMANDS) / sizeof(char*),
+                IPT_CLEANUP_COMMANDS, RunCmdFailureOk);
+    }
+}
+
+int BandwidthController::setupIptablesHooks(void) {
+
+    /* flush+clean is allowed to fail */
+    flushCleanTables(true);
+    runCommands(sizeof(IPT_SETUP_COMMANDS) / sizeof(char*),
+            IPT_SETUP_COMMANDS, RunCmdFailureBad);
+
+    return 0;
+}
+
+int BandwidthController::enableBandwidthControl(bool force) {
+    int res;
+    char value[PROPERTY_VALUE_MAX];
+
+    if (!force) {
+            property_get("persist.bandwidth.enable", value, "1");
+            if (!strcmp(value, "0"))
+                    return 0;
+    }
+
+    /* Let's pretend we started from scratch ... */
+    sharedQuotaIfaces.clear();
+    quotaIfaces.clear();
+    naughtyAppUids.clear();
+    niceAppUids.clear();
+    globalAlertBytes = 0;
+    globalAlertTetherCount = 0;
+    sharedQuotaBytes = sharedAlertBytes = 0;
+
+    flushCleanTables(false);
+    res = runCommands(sizeof(IPT_BASIC_ACCOUNTING_COMMANDS) / sizeof(char*),
+            IPT_BASIC_ACCOUNTING_COMMANDS, RunCmdFailureBad);
+
+    return res;
+
+}
+
+int BandwidthController::disableBandwidthControl(void) {
+
+    flushCleanTables(false);
+    return 0;
+}
+
+int BandwidthController::runCommands(int numCommands, const char *commands[],
+                                     RunCmdErrHandling cmdErrHandling) {
+    int res = 0;
+    IptFailureLog failureLogging = IptFailShow;
+    if (cmdErrHandling == RunCmdFailureOk) {
+        failureLogging = IptFailHide;
+    }
+    ALOGV("runCommands(): %d commands", numCommands);
+    for (int cmdNum = 0; cmdNum < numCommands; cmdNum++) {
+        res = runIpxtablesCmd(commands[cmdNum], IptJumpNoAdd, failureLogging);
+        if (res && cmdErrHandling != RunCmdFailureOk)
+            return res;
+    }
+    return 0;
+}
+
+std::string BandwidthController::makeIptablesSpecialAppCmd(IptOp op, int uid, const char *chain) {
+    std::string res;
+    char *buff;
+    const char *opFlag;
+
+    switch (op) {
+    case IptOpInsert:
+        opFlag = "-I";
+        break;
+    case IptOpAppend:
+        ALOGE("Append op not supported for %s uids", chain);
+        res = "";
+        return res;
+        break;
+    case IptOpReplace:
+        opFlag = "-R";
+        break;
+    default:
+    case IptOpDelete:
+        opFlag = "-D";
+        break;
+    }
+    asprintf(&buff, "%s %s -m owner --uid-owner %d", opFlag, chain, uid);
+    res = buff;
+    free(buff);
+    return res;
+}
+
+int BandwidthController::enableHappyBox(void) {
+    char cmd[MAX_CMD_LEN];
+    int res = 0;
+
+    /*
+     * We tentatively delete before adding, which helps recovering
+     * from bad states (e.g. netd died).
+     */
+
+    /* Should not exist, but ignore result if already there. */
+    snprintf(cmd, sizeof(cmd), "-N bw_happy_box");
+    runIpxtablesCmd(cmd, IptJumpNoAdd);
+
+    /* Should be empty, but clear in case something was wrong. */
+    niceAppUids.clear();
+    snprintf(cmd, sizeof(cmd), "-F bw_happy_box");
+    res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+
+    snprintf(cmd, sizeof(cmd), "-D bw_penalty_box -j bw_happy_box");
+    runIpxtablesCmd(cmd, IptJumpNoAdd);
+    snprintf(cmd, sizeof(cmd), "-A bw_penalty_box -j bw_happy_box");
+    res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+
+    /* Reject. Defaulting to prot-unreachable */
+    snprintf(cmd, sizeof(cmd), "-D bw_happy_box -j REJECT");
+    runIpxtablesCmd(cmd, IptJumpNoAdd);
+    snprintf(cmd, sizeof(cmd), "-A bw_happy_box -j REJECT");
+    res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+
+    return res;
+}
+
+int BandwidthController::disableHappyBox(void) {
+    char cmd[MAX_CMD_LEN];
+
+    /* Best effort */
+    snprintf(cmd, sizeof(cmd), "-D bw_penalty_box -j bw_happy_box");
+    runIpxtablesCmd(cmd, IptJumpNoAdd);
+    niceAppUids.clear();
+    snprintf(cmd, sizeof(cmd), "-F bw_happy_box");
+    runIpxtablesCmd(cmd, IptJumpNoAdd);
+    snprintf(cmd, sizeof(cmd), "-X bw_happy_box");
+    runIpxtablesCmd(cmd, IptJumpNoAdd);
+
+    return 0;
+}
+
+int BandwidthController::addNaughtyApps(int numUids, char *appUids[]) {
+    return manipulateNaughtyApps(numUids, appUids, SpecialAppOpAdd);
+}
+
+int BandwidthController::removeNaughtyApps(int numUids, char *appUids[]) {
+    return manipulateNaughtyApps(numUids, appUids, SpecialAppOpRemove);
+}
+
+int BandwidthController::addNiceApps(int numUids, char *appUids[]) {
+    return manipulateNiceApps(numUids, appUids, SpecialAppOpAdd);
+}
+
+int BandwidthController::removeNiceApps(int numUids, char *appUids[]) {
+    return manipulateNiceApps(numUids, appUids, SpecialAppOpRemove);
+}
+
+int BandwidthController::manipulateNaughtyApps(int numUids, char *appStrUids[], SpecialAppOp appOp) {
+    return manipulateSpecialApps(numUids, appStrUids, "bw_penalty_box", naughtyAppUids, IptJumpReject, appOp);
+}
+
+int BandwidthController::manipulateNiceApps(int numUids, char *appStrUids[], SpecialAppOp appOp) {
+    return manipulateSpecialApps(numUids, appStrUids, "bw_happy_box", niceAppUids, IptJumpReturn, appOp);
+}
+
+
+int BandwidthController::manipulateSpecialApps(int numUids, char *appStrUids[],
+                                               const char *chain,
+                                               std::list<int /*appUid*/> &specialAppUids,
+                                               IptJumpOp jumpHandling, SpecialAppOp appOp) {
+
+    int uidNum;
+    const char *failLogTemplate;
+    IptOp op;
+    int appUids[numUids];
+    std::string iptCmd;
+    std::list<int /*uid*/>::iterator it;
+
+    switch (appOp) {
+    case SpecialAppOpAdd:
+        op = IptOpInsert;
+        failLogTemplate = "Failed to add app uid %s(%d) to %s.";
+        break;
+    case SpecialAppOpRemove:
+        op = IptOpDelete;
+        failLogTemplate = "Failed to delete app uid %s(%d) from %s box.";
+        break;
+    default:
+        ALOGE("Unexpected app Op %d", appOp);
+        return -1;
+    }
+
+    for (uidNum = 0; uidNum < numUids; uidNum++) {
+        char *end;
+        appUids[uidNum] = strtoul(appStrUids[uidNum], &end, 0);
+        if (*end || !*appStrUids[uidNum]) {
+            ALOGE(failLogTemplate, appStrUids[uidNum], appUids[uidNum], chain);
+            goto fail_parse;
+        }
+    }
+
+    for (uidNum = 0; uidNum < numUids; uidNum++) {
+        int uid = appUids[uidNum];
+        for (it = specialAppUids.begin(); it != specialAppUids.end(); it++) {
+            if (*it == uid)
+                break;
+        }
+        bool found = (it != specialAppUids.end());
+
+        if (appOp == SpecialAppOpRemove) {
+            if (!found) {
+                ALOGE("No such appUid %d to remove", uid);
+                return -1;
+            }
+            specialAppUids.erase(it);
+        } else {
+            if (found) {
+                ALOGE("appUid %d exists already", uid);
+                return -1;
+            }
+            specialAppUids.push_front(uid);
+        }
+
+        iptCmd = makeIptablesSpecialAppCmd(op, uid, chain);
+        if (runIpxtablesCmd(iptCmd.c_str(), jumpHandling)) {
+            ALOGE(failLogTemplate, appStrUids[uidNum], uid, chain);
+            goto fail_with_uidNum;
+        }
+    }
+    return 0;
+
+fail_with_uidNum:
+    /* Try to remove the uid that failed in any case*/
+    iptCmd = makeIptablesSpecialAppCmd(IptOpDelete, appUids[uidNum], chain);
+    runIpxtablesCmd(iptCmd.c_str(), jumpHandling);
+fail_parse:
+    return -1;
+}
+
+std::string BandwidthController::makeIptablesQuotaCmd(IptOp op, const char *costName, int64_t quota) {
+    std::string res;
+    char *buff;
+    const char *opFlag;
+
+    ALOGV("makeIptablesQuotaCmd(%d, %" PRId64")", op, quota);
+
+    switch (op) {
+    case IptOpInsert:
+        opFlag = "-I";
+        break;
+    case IptOpAppend:
+        opFlag = "-A";
+        break;
+    case IptOpReplace:
+        opFlag = "-R";
+        break;
+    default:
+    case IptOpDelete:
+        opFlag = "-D";
+        break;
+    }
+
+    // The requried IP version specific --jump REJECT ... will be added later.
+    asprintf(&buff, "%s bw_costly_%s -m quota2 ! --quota %" PRId64" --name %s", opFlag, costName, quota,
+             costName);
+    res = buff;
+    free(buff);
+    return res;
+}
+
+int BandwidthController::prepCostlyIface(const char *ifn, QuotaType quotaType) {
+    char cmd[MAX_CMD_LEN];
+    int res = 0, res1, res2;
+    int ruleInsertPos = 1;
+    std::string costString;
+    const char *costCString;
+
+    /* The "-N costly" is created upfront, no need to handle it here. */
+    switch (quotaType) {
+    case QuotaUnique:
+        costString = "bw_costly_";
+        costString += ifn;
+        costCString = costString.c_str();
+        /*
+         * Flush the bw_costly_<iface> is allowed to fail in case it didn't exist.
+         * Creating a new one is allowed to fail in case it existed.
+         * This helps with netd restarts.
+         */
+        snprintf(cmd, sizeof(cmd), "-F %s", costCString);
+        res1 = runIpxtablesCmd(cmd, IptJumpNoAdd, IptFailHide);
+        snprintf(cmd, sizeof(cmd), "-N %s", costCString);
+        res2 = runIpxtablesCmd(cmd, IptJumpNoAdd, IptFailHide);
+        res = (res1 && res2) || (!res1 && !res2);
+
+        snprintf(cmd, sizeof(cmd), "-A %s -j bw_penalty_box", costCString);
+        res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+        break;
+    case QuotaShared:
+        costCString = "bw_costly_shared";
+        break;
+    default:
+        ALOGE("Unexpected quotatype %d", quotaType);
+        return -1;
+    }
+
+    if (globalAlertBytes) {
+        /* The alert rule comes 1st */
+        ruleInsertPos = 2;
+    }
+
+    snprintf(cmd, sizeof(cmd), "-D bw_INPUT -i %s --jump %s", ifn, costCString);
+    runIpxtablesCmd(cmd, IptJumpNoAdd, IptFailHide);
+
+    snprintf(cmd, sizeof(cmd), "-I bw_INPUT %d -i %s --jump %s", ruleInsertPos, ifn, costCString);
+    res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+
+    snprintf(cmd, sizeof(cmd), "-D bw_OUTPUT -o %s --jump %s", ifn, costCString);
+    runIpxtablesCmd(cmd, IptJumpNoAdd, IptFailHide);
+
+    snprintf(cmd, sizeof(cmd), "-I bw_OUTPUT %d -o %s --jump %s", ruleInsertPos, ifn, costCString);
+    res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+    return res;
+}
+
+int BandwidthController::cleanupCostlyIface(const char *ifn, QuotaType quotaType) {
+    char cmd[MAX_CMD_LEN];
+    int res = 0;
+    std::string costString;
+    const char *costCString;
+
+    switch (quotaType) {
+    case QuotaUnique:
+        costString = "bw_costly_";
+        costString += ifn;
+        costCString = costString.c_str();
+        break;
+    case QuotaShared:
+        costCString = "bw_costly_shared";
+        break;
+    default:
+        ALOGE("Unexpected quotatype %d", quotaType);
+        return -1;
+    }
+
+    snprintf(cmd, sizeof(cmd), "-D bw_INPUT -i %s --jump %s", ifn, costCString);
+    res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+    snprintf(cmd, sizeof(cmd), "-D bw_OUTPUT -o %s --jump %s", ifn, costCString);
+    res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+
+    /* The "-N bw_costly_shared" is created upfront, no need to handle it here. */
+    if (quotaType == QuotaUnique) {
+        snprintf(cmd, sizeof(cmd), "-F %s", costCString);
+        res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+        snprintf(cmd, sizeof(cmd), "-X %s", costCString);
+        res |= runIpxtablesCmd(cmd, IptJumpNoAdd);
+    }
+    return res;
+}
+
+int BandwidthController::setInterfaceSharedQuota(const char *iface, int64_t maxBytes) {
+    char ifn[MAX_IFACENAME_LEN];
+    int res = 0;
+    std::string quotaCmd;
+    std::string ifaceName;
+    ;
+    const char *costName = "shared";
+    std::list<std::string>::iterator it;
+
+    if (!maxBytes) {
+        /* Don't talk about -1, deprecate it. */
+        ALOGE("Invalid bytes value. 1..max_int64.");
+        return -1;
+    }
+    if (!isIfaceName(iface))
+        return -1;
+    if (StrncpyAndCheck(ifn, iface, sizeof(ifn))) {
+        ALOGE("Interface name longer than %d", MAX_IFACENAME_LEN);
+        return -1;
+    }
+    ifaceName = ifn;
+
+    if (maxBytes == -1) {
+        return removeInterfaceSharedQuota(ifn);
+    }
+
+    /* Insert ingress quota. */
+    for (it = sharedQuotaIfaces.begin(); it != sharedQuotaIfaces.end(); it++) {
+        if (*it == ifaceName)
+            break;
+    }
+
+    if (it == sharedQuotaIfaces.end()) {
+        res |= prepCostlyIface(ifn, QuotaShared);
+        if (sharedQuotaIfaces.empty()) {
+            quotaCmd = makeIptablesQuotaCmd(IptOpInsert, costName, maxBytes);
+            res |= runIpxtablesCmd(quotaCmd.c_str(), IptJumpReject);
+            if (res) {
+                ALOGE("Failed set quota rule");
+                goto fail;
+            }
+            sharedQuotaBytes = maxBytes;
+        }
+        sharedQuotaIfaces.push_front(ifaceName);
+
+    }
+
+    if (maxBytes != sharedQuotaBytes) {
+        res |= updateQuota(costName, maxBytes);
+        if (res) {
+            ALOGE("Failed update quota for %s", costName);
+            goto fail;
+        }
+        sharedQuotaBytes = maxBytes;
+    }
+    return 0;
+
+    fail:
+    /*
+     * TODO(jpa): once we get rid of iptables in favor of rtnetlink, reparse
+     * rules in the kernel to see which ones need cleaning up.
+     * For now callers needs to choose if they want to "ndc bandwidth enable"
+     * which resets everything.
+     */
+    removeInterfaceSharedQuota(ifn);
+    return -1;
+}
+
+/* It will also cleanup any shared alerts */
+int BandwidthController::removeInterfaceSharedQuota(const char *iface) {
+    char ifn[MAX_IFACENAME_LEN];
+    int res = 0;
+    std::string ifaceName;
+    std::list<std::string>::iterator it;
+    const char *costName = "shared";
+
+    if (!isIfaceName(iface))
+        return -1;
+    if (StrncpyAndCheck(ifn, iface, sizeof(ifn))) {
+        ALOGE("Interface name longer than %d", MAX_IFACENAME_LEN);
+        return -1;
+    }
+    ifaceName = ifn;
+
+    for (it = sharedQuotaIfaces.begin(); it != sharedQuotaIfaces.end(); it++) {
+        if (*it == ifaceName)
+            break;
+    }
+    if (it == sharedQuotaIfaces.end()) {
+        ALOGE("No such iface %s to delete", ifn);
+        return -1;
+    }
+
+    res |= cleanupCostlyIface(ifn, QuotaShared);
+    sharedQuotaIfaces.erase(it);
+
+    if (sharedQuotaIfaces.empty()) {
+        std::string quotaCmd;
+        quotaCmd = makeIptablesQuotaCmd(IptOpDelete, costName, sharedQuotaBytes);
+        res |= runIpxtablesCmd(quotaCmd.c_str(), IptJumpReject);
+        sharedQuotaBytes = 0;
+        if (sharedAlertBytes) {
+            removeSharedAlert();
+            sharedAlertBytes = 0;
+        }
+    }
+    return res;
+}
+
+int BandwidthController::setInterfaceQuota(const char *iface, int64_t maxBytes) {
+    char ifn[MAX_IFACENAME_LEN];
+    int res = 0;
+    std::string ifaceName;
+    const char *costName;
+    std::list<QuotaInfo>::iterator it;
+    std::string quotaCmd;
+
+    if (!isIfaceName(iface))
+        return -1;
+
+    if (!maxBytes) {
+        /* Don't talk about -1, deprecate it. */
+        ALOGE("Invalid bytes value. 1..max_int64.");
+        return -1;
+    }
+    if (maxBytes == -1) {
+        return removeInterfaceQuota(iface);
+    }
+
+    if (StrncpyAndCheck(ifn, iface, sizeof(ifn))) {
+        ALOGE("Interface name longer than %d", MAX_IFACENAME_LEN);
+        return -1;
+    }
+    ifaceName = ifn;
+    costName = iface;
+
+    /* Insert ingress quota. */
+    for (it = quotaIfaces.begin(); it != quotaIfaces.end(); it++) {
+        if (it->ifaceName == ifaceName)
+            break;
+    }
+
+    if (it == quotaIfaces.end()) {
+        /* Preparing the iface adds a penalty/happy box check */
+        res |= prepCostlyIface(ifn, QuotaUnique);
+        /*
+         * The rejecting quota limit should go after the penalty/happy box checks
+         * or else a naughty app could just eat up the quota.
+         * So we append here.
+         */
+        quotaCmd = makeIptablesQuotaCmd(IptOpAppend, costName, maxBytes);
+        res |= runIpxtablesCmd(quotaCmd.c_str(), IptJumpReject);
+        if (res) {
+            ALOGE("Failed set quota rule");
+            goto fail;
+        }
+
+        quotaIfaces.push_front(QuotaInfo(ifaceName, maxBytes, 0));
+
+    } else {
+        res |= updateQuota(costName, maxBytes);
+        if (res) {
+            ALOGE("Failed update quota for %s", iface);
+            goto fail;
+        }
+        it->quota = maxBytes;
+    }
+    return 0;
+
+    fail:
+    /*
+     * TODO(jpa): once we get rid of iptables in favor of rtnetlink, reparse
+     * rules in the kernel to see which ones need cleaning up.
+     * For now callers needs to choose if they want to "ndc bandwidth enable"
+     * which resets everything.
+     */
+    removeInterfaceSharedQuota(ifn);
+    return -1;
+}
+
+int BandwidthController::getInterfaceSharedQuota(int64_t *bytes) {
+    return getInterfaceQuota("shared", bytes);
+}
+
+int BandwidthController::getInterfaceQuota(const char *costName, int64_t *bytes) {
+    FILE *fp;
+    char *fname;
+    int scanRes;
+
+    if (!isIfaceName(costName))
+        return -1;
+
+    asprintf(&fname, "/proc/net/xt_quota/%s", costName);
+    fp = fopen(fname, "re");
+    free(fname);
+    if (!fp) {
+        ALOGE("Reading quota %s failed (%s)", costName, strerror(errno));
+        return -1;
+    }
+    scanRes = fscanf(fp, "%" SCNd64, bytes);
+    ALOGV("Read quota res=%d bytes=%" PRId64, scanRes, *bytes);
+    fclose(fp);
+    return scanRes == 1 ? 0 : -1;
+}
+
+int BandwidthController::removeInterfaceQuota(const char *iface) {
+
+    char ifn[MAX_IFACENAME_LEN];
+    int res = 0;
+    std::string ifaceName;
+    const char *costName;
+    std::list<QuotaInfo>::iterator it;
+
+    if (!isIfaceName(iface))
+        return -1;
+    if (StrncpyAndCheck(ifn, iface, sizeof(ifn))) {
+        ALOGE("Interface name longer than %d", MAX_IFACENAME_LEN);
+        return -1;
+    }
+    ifaceName = ifn;
+    costName = iface;
+
+    for (it = quotaIfaces.begin(); it != quotaIfaces.end(); it++) {
+        if (it->ifaceName == ifaceName)
+            break;
+    }
+
+    if (it == quotaIfaces.end()) {
+        ALOGE("No such iface %s to delete", ifn);
+        return -1;
+    }
+
+    /* This also removes the quota command of CostlyIface chain. */
+    res |= cleanupCostlyIface(ifn, QuotaUnique);
+
+    quotaIfaces.erase(it);
+
+    return res;
+}
+
+int BandwidthController::updateQuota(const char *quotaName, int64_t bytes) {
+    FILE *fp;
+    char *fname;
+
+    if (!isIfaceName(quotaName)) {
+        ALOGE("updateQuota: Invalid quotaName \"%s\"", quotaName);
+        return -1;
+    }
+
+    asprintf(&fname, "/proc/net/xt_quota/%s", quotaName);
+    fp = fopen(fname, "we");
+    free(fname);
+    if (!fp) {
+        ALOGE("Updating quota %s failed (%s)", quotaName, strerror(errno));
+        return -1;
+    }
+    fprintf(fp, "%" PRId64"\n", bytes);
+    fclose(fp);
+    return 0;
+}
+
+int BandwidthController::runIptablesAlertCmd(IptOp op, const char *alertName, int64_t bytes) {
+    int res = 0;
+    const char *opFlag;
+    char *alertQuotaCmd;
+
+    switch (op) {
+    case IptOpInsert:
+        opFlag = "-I";
+        break;
+    case IptOpAppend:
+        opFlag = "-A";
+        break;
+    case IptOpReplace:
+        opFlag = "-R";
+        break;
+    default:
+    case IptOpDelete:
+        opFlag = "-D";
+        break;
+    }
+
+    asprintf(&alertQuotaCmd, ALERT_IPT_TEMPLATE, opFlag, "bw_INPUT",
+        bytes, alertName);
+    res |= runIpxtablesCmd(alertQuotaCmd, IptJumpNoAdd);
+    free(alertQuotaCmd);
+    asprintf(&alertQuotaCmd, ALERT_IPT_TEMPLATE, opFlag, "bw_OUTPUT",
+        bytes, alertName);
+    res |= runIpxtablesCmd(alertQuotaCmd, IptJumpNoAdd);
+    free(alertQuotaCmd);
+    return res;
+}
+
+int BandwidthController::runIptablesAlertFwdCmd(IptOp op, const char *alertName, int64_t bytes) {
+    int res = 0;
+    const char *opFlag;
+    char *alertQuotaCmd;
+
+    switch (op) {
+    case IptOpInsert:
+        opFlag = "-I";
+        break;
+    case IptOpAppend:
+        opFlag = "-A";
+        break;
+    case IptOpReplace:
+        opFlag = "-R";
+        break;
+    default:
+    case IptOpDelete:
+        opFlag = "-D";
+        break;
+    }
+
+    asprintf(&alertQuotaCmd, ALERT_IPT_TEMPLATE, opFlag, "bw_FORWARD",
+        bytes, alertName);
+    res = runIpxtablesCmd(alertQuotaCmd, IptJumpNoAdd);
+    free(alertQuotaCmd);
+    return res;
+}
+
+int BandwidthController::setGlobalAlert(int64_t bytes) {
+    const char *alertName = ALERT_GLOBAL_NAME;
+    int res = 0;
+
+    if (!bytes) {
+        ALOGE("Invalid bytes value. 1..max_int64.");
+        return -1;
+    }
+    if (globalAlertBytes) {
+        res = updateQuota(alertName, bytes);
+    } else {
+        res = runIptablesAlertCmd(IptOpInsert, alertName, bytes);
+        if (globalAlertTetherCount) {
+            ALOGV("setGlobalAlert for %d tether", globalAlertTetherCount);
+            res |= runIptablesAlertFwdCmd(IptOpInsert, alertName, bytes);
+        }
+    }
+    globalAlertBytes = bytes;
+    return res;
+}
+
+int BandwidthController::setGlobalAlertInForwardChain(void) {
+    const char *alertName = ALERT_GLOBAL_NAME;
+    int res = 0;
+
+    globalAlertTetherCount++;
+    ALOGV("setGlobalAlertInForwardChain(): %d tether", globalAlertTetherCount);
+
+    /*
+     * If there is no globalAlert active we are done.
+     * If there is an active globalAlert but this is not the 1st
+     * tether, we are also done.
+     */
+    if (!globalAlertBytes || globalAlertTetherCount != 1) {
+        return 0;
+    }
+
+    /* We only add the rule if this was the 1st tether added. */
+    res = runIptablesAlertFwdCmd(IptOpInsert, alertName, globalAlertBytes);
+    return res;
+}
+
+int BandwidthController::removeGlobalAlert(void) {
+
+    const char *alertName = ALERT_GLOBAL_NAME;
+    int res = 0;
+
+    if (!globalAlertBytes) {
+        ALOGE("No prior alert set");
+        return -1;
+    }
+    res = runIptablesAlertCmd(IptOpDelete, alertName, globalAlertBytes);
+    if (globalAlertTetherCount) {
+        res |= runIptablesAlertFwdCmd(IptOpDelete, alertName, globalAlertBytes);
+    }
+    globalAlertBytes = 0;
+    return res;
+}
+
+int BandwidthController::removeGlobalAlertInForwardChain(void) {
+    int res = 0;
+    const char *alertName = ALERT_GLOBAL_NAME;
+
+    if (!globalAlertTetherCount) {
+        ALOGE("No prior alert set");
+        return -1;
+    }
+
+    globalAlertTetherCount--;
+    /*
+     * If there is no globalAlert active we are done.
+     * If there is an active globalAlert but there are more
+     * tethers, we are also done.
+     */
+    if (!globalAlertBytes || globalAlertTetherCount >= 1) {
+        return 0;
+    }
+
+    /* We only detete the rule if this was the last tether removed. */
+    res = runIptablesAlertFwdCmd(IptOpDelete, alertName, globalAlertBytes);
+    return res;
+}
+
+int BandwidthController::setSharedAlert(int64_t bytes) {
+    if (!sharedQuotaBytes) {
+        ALOGE("Need to have a prior shared quota set to set an alert");
+        return -1;
+    }
+    if (!bytes) {
+        ALOGE("Invalid bytes value. 1..max_int64.");
+        return -1;
+    }
+    return setCostlyAlert("shared", bytes, &sharedAlertBytes);
+}
+
+int BandwidthController::removeSharedAlert(void) {
+    return removeCostlyAlert("shared", &sharedAlertBytes);
+}
+
+int BandwidthController::setInterfaceAlert(const char *iface, int64_t bytes) {
+    std::list<QuotaInfo>::iterator it;
+
+    if (!isIfaceName(iface)) {
+        ALOGE("setInterfaceAlert: Invalid iface \"%s\"", iface);
+        return -1;
+    }
+
+    if (!bytes) {
+        ALOGE("Invalid bytes value. 1..max_int64.");
+        return -1;
+    }
+    for (it = quotaIfaces.begin(); it != quotaIfaces.end(); it++) {
+        if (it->ifaceName == iface)
+            break;
+    }
+
+    if (it == quotaIfaces.end()) {
+        ALOGE("Need to have a prior interface quota set to set an alert");
+        return -1;
+    }
+
+    return setCostlyAlert(iface, bytes, &it->alert);
+}
+
+int BandwidthController::removeInterfaceAlert(const char *iface) {
+    std::list<QuotaInfo>::iterator it;
+
+    if (!isIfaceName(iface)) {
+        ALOGE("removeInterfaceAlert: Invalid iface \"%s\"", iface);
+        return -1;
+    }
+
+    for (it = quotaIfaces.begin(); it != quotaIfaces.end(); it++) {
+        if (it->ifaceName == iface)
+            break;
+    }
+
+    if (it == quotaIfaces.end()) {
+        ALOGE("No prior alert set for interface %s", iface);
+        return -1;
+    }
+
+    return removeCostlyAlert(iface, &it->alert);
+}
+
+int BandwidthController::setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes) {
+    char *alertQuotaCmd;
+    char *chainName;
+    int res = 0;
+    char *alertName;
+
+    if (!isIfaceName(costName)) {
+        ALOGE("setCostlyAlert: Invalid costName \"%s\"", costName);
+        return -1;
+    }
+
+    if (!bytes) {
+        ALOGE("Invalid bytes value. 1..max_int64.");
+        return -1;
+    }
+    asprintf(&alertName, "%sAlert", costName);
+    if (*alertBytes) {
+        res = updateQuota(alertName, *alertBytes);
+    } else {
+        asprintf(&chainName, "bw_costly_%s", costName);
+        asprintf(&alertQuotaCmd, ALERT_IPT_TEMPLATE, "-A", chainName, bytes, alertName);
+        res |= runIpxtablesCmd(alertQuotaCmd, IptJumpNoAdd);
+        free(alertQuotaCmd);
+        free(chainName);
+    }
+    *alertBytes = bytes;
+    free(alertName);
+    return res;
+}
+
+int BandwidthController::removeCostlyAlert(const char *costName, int64_t *alertBytes) {
+    char *alertQuotaCmd;
+    char *chainName;
+    char *alertName;
+    int res = 0;
+
+    if (!isIfaceName(costName)) {
+        ALOGE("removeCostlyAlert: Invalid costName \"%s\"", costName);
+        return -1;
+    }
+
+    if (!*alertBytes) {
+        ALOGE("No prior alert set for %s alert", costName);
+        return -1;
+    }
+
+    asprintf(&alertName, "%sAlert", costName);
+    asprintf(&chainName, "bw_costly_%s", costName);
+    asprintf(&alertQuotaCmd, ALERT_IPT_TEMPLATE, "-D", chainName, *alertBytes, alertName);
+    res |= runIpxtablesCmd(alertQuotaCmd, IptJumpNoAdd);
+    free(alertQuotaCmd);
+    free(chainName);
+
+    *alertBytes = 0;
+    free(alertName);
+    return res;
+}
+
+/*
+ * Parse the ptks and bytes out of:
+ *   Chain natctrl_tether_counters (4 references)
+ *       pkts      bytes target     prot opt in     out     source               destination
+ *         26     2373 RETURN     all  --  wlan0  rmnet0  0.0.0.0/0            0.0.0.0/0
+ *         27     2002 RETURN     all  --  rmnet0 wlan0   0.0.0.0/0            0.0.0.0/0
+ *       1040   107471 RETURN     all  --  bt-pan rmnet0  0.0.0.0/0            0.0.0.0/0
+ *       1450  1708806 RETURN     all  --  rmnet0 bt-pan  0.0.0.0/0            0.0.0.0/0
+ * It results in an error if invoked and no tethering counter rules exist. The constraint
+ * helps detect complete parsing failure.
+ */
+int BandwidthController::parseForwardChainStats(SocketClient *cli, const TetherStats filter,
+                                                FILE *fp, std::string &extraProcessingInfo) {
+    int res;
+    char lineBuffer[MAX_IPT_OUTPUT_LINE_LEN];
+    char iface0[MAX_IPT_OUTPUT_LINE_LEN];
+    char iface1[MAX_IPT_OUTPUT_LINE_LEN];
+    char rest[MAX_IPT_OUTPUT_LINE_LEN];
+
+    TetherStats stats;
+    char *buffPtr;
+    int64_t packets, bytes;
+    int statsFound = 0;
+
+    bool filterPair = filter.intIface[0] && filter.extIface[0];
+
+    char *filterMsg = filter.getStatsLine();
+    ALOGV("filter: %s",  filterMsg);
+    free(filterMsg);
+
+    stats = filter;
+
+    while (NULL != (buffPtr = fgets(lineBuffer, MAX_IPT_OUTPUT_LINE_LEN, fp))) {
+        /* Clean up, so a failed parse can still print info */
+        iface0[0] = iface1[0] = rest[0] = packets = bytes = 0;
+        res = sscanf(buffPtr, "%" SCNd64" %" SCNd64" RETURN all -- %s %s 0.%s",
+                &packets, &bytes, iface0, iface1, rest);
+        ALOGV("parse res=%d iface0=<%s> iface1=<%s> pkts=%" PRId64" bytes=%" PRId64" rest=<%s> orig line=<%s>", res,
+             iface0, iface1, packets, bytes, rest, buffPtr);
+        extraProcessingInfo += buffPtr;
+
+        if (res != 5) {
+            continue;
+        }
+        /*
+         * The following assumes that the 1st rule has in:extIface out:intIface,
+         * which is what NatController sets up.
+         * If not filtering, the 1st match rx, and sets up the pair for the tx side.
+         */
+        if (filter.intIface[0] && filter.extIface[0]) {
+            if (filter.intIface == iface0 && filter.extIface == iface1) {
+                ALOGV("2Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
+                stats.rxPackets = packets;
+                stats.rxBytes = bytes;
+            } else if (filter.intIface == iface1 && filter.extIface == iface0) {
+                ALOGV("2Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
+                stats.txPackets = packets;
+                stats.txBytes = bytes;
+            }
+        } else if (filter.intIface[0] || filter.extIface[0]) {
+            if (filter.intIface == iface0 || filter.extIface == iface1) {
+                ALOGV("1Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
+                stats.intIface = iface0;
+                stats.extIface = iface1;
+                stats.rxPackets = packets;
+                stats.rxBytes = bytes;
+            } else if (filter.intIface == iface1 || filter.extIface == iface0) {
+                ALOGV("1Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
+                stats.intIface = iface1;
+                stats.extIface = iface0;
+                stats.txPackets = packets;
+                stats.txBytes = bytes;
+            }
+        } else /* if (!filter.intFace[0] && !filter.extIface[0]) */ {
+            if (!stats.intIface[0]) {
+                ALOGV("0Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
+                stats.intIface = iface0;
+                stats.extIface = iface1;
+                stats.rxPackets = packets;
+                stats.rxBytes = bytes;
+            } else if (stats.intIface == iface1 && stats.extIface == iface0) {
+                ALOGV("0Filter TX iface_in=%s iface_out=%s rx_bytes=%" PRId64" rx_packets=%" PRId64" ", iface0, iface1, bytes, packets);
+                stats.txPackets = packets;
+                stats.txBytes = bytes;
+            }
+        }
+        if (stats.rxBytes != -1 && stats.txBytes != -1) {
+            ALOGV("rx_bytes=%" PRId64" tx_bytes=%" PRId64" filterPair=%d", stats.rxBytes, stats.txBytes, filterPair);
+            /* Send out stats, and prep for the next if needed. */
+            char *msg = stats.getStatsLine();
+            if (filterPair) {
+                cli->sendMsg(ResponseCode::TetheringStatsResult, msg, false);
+                return 0;
+            } else {
+                cli->sendMsg(ResponseCode::TetheringStatsListResult, msg, false);
+                stats = filter;
+            }
+            free(msg);
+            statsFound++;
+        }
+    }
+
+    /* It is always an error to find only one side of the stats. */
+    /* It is an error to find nothing when not filtering. */
+    if (((stats.rxBytes == -1) != (stats.txBytes == -1)) ||
+        (!statsFound && !filterPair)) {
+        return -1;
+    }
+    cli->sendMsg(ResponseCode::CommandOkay, "Tethering stats list completed", false);
+    return 0;
+}
+
+char *BandwidthController::TetherStats::getStatsLine(void) const {
+    char *msg;
+    asprintf(&msg, "%s %s %" PRId64" %" PRId64" %" PRId64" %" PRId64, intIface.c_str(), extIface.c_str(),
+            rxBytes, rxPackets, txBytes, txPackets);
+    return msg;
+}
+
+int BandwidthController::getTetherStats(SocketClient *cli, TetherStats &stats, std::string &extraProcessingInfo) {
+    int res;
+    std::string fullCmd;
+    FILE *iptOutput;
+
+    /*
+     * Why not use some kind of lib to talk to iptables?
+     * Because the only libs are libiptc and libip6tc in iptables, and they are
+     * not easy to use. They require the known iptables match modules to be
+     * preloaded/linked, and require apparently a lot of wrapper code to get
+     * the wanted info.
+     */
+    fullCmd = IPTABLES_PATH;
+    fullCmd += " -nvx -w -L ";
+    fullCmd += NatController::LOCAL_TETHER_COUNTERS_CHAIN;
+    iptOutput = popen(fullCmd.c_str(), "r");
+    if (!iptOutput) {
+            ALOGE("Failed to run %s err=%s", fullCmd.c_str(), strerror(errno));
+            extraProcessingInfo += "Failed to run iptables.";
+        return -1;
+    }
+    res = parseForwardChainStats(cli, stats, iptOutput, extraProcessingInfo);
+    pclose(iptOutput);
+
+    /* Currently NatController doesn't do ipv6 tethering, so we are done. */
+    return res;
+}
+
+void BandwidthController::flushExistingCostlyTables(bool doClean) {
+    std::string fullCmd;
+    FILE *iptOutput;
+
+    /* Only lookup ip4 table names as ip6 will have the same tables ... */
+    fullCmd = IPTABLES_PATH;
+    fullCmd += " -w -S";
+    iptOutput = popen(fullCmd.c_str(), "r");
+    if (!iptOutput) {
+            ALOGE("Failed to run %s err=%s", fullCmd.c_str(), strerror(errno));
+        return;
+    }
+    /* ... then flush/clean both ip4 and ip6 iptables. */
+    parseAndFlushCostlyTables(iptOutput, doClean);
+    pclose(iptOutput);
+}
+
+void BandwidthController::parseAndFlushCostlyTables(FILE *fp, bool doRemove) {
+    int res;
+    char lineBuffer[MAX_IPT_OUTPUT_LINE_LEN];
+    char costlyIfaceName[MAX_IPT_OUTPUT_LINE_LEN];
+    char cmd[MAX_CMD_LEN];
+    char *buffPtr;
+
+    while (NULL != (buffPtr = fgets(lineBuffer, MAX_IPT_OUTPUT_LINE_LEN, fp))) {
+        costlyIfaceName[0] = '\0';   /* So that debugging output always works */
+        res = sscanf(buffPtr, "-N bw_costly_%s", costlyIfaceName);
+        ALOGV("parse res=%d costly=<%s> orig line=<%s>", res,
+            costlyIfaceName, buffPtr);
+        if (res != 1) {
+            continue;
+        }
+        /* Exclusions: "shared" is not an ifacename */
+        if (!strcmp(costlyIfaceName, "shared")) {
+            continue;
+        }
+
+        snprintf(cmd, sizeof(cmd), "-F bw_costly_%s", costlyIfaceName);
+        runIpxtablesCmd(cmd, IptJumpNoAdd, IptFailHide);
+        if (doRemove) {
+            snprintf(cmd, sizeof(cmd), "-X bw_costly_%s", costlyIfaceName);
+            runIpxtablesCmd(cmd, IptJumpNoAdd, IptFailHide);
+        }
+    }
+}
diff --git a/netd/server/BandwidthController.h b/netd/server/BandwidthController.h
new file mode 100644
index 0000000..2aca2cd
--- /dev/null
+++ b/netd/server/BandwidthController.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+#ifndef _BANDWIDTH_CONTROLLER_H
+#define _BANDWIDTH_CONTROLLER_H
+
+#include <list>
+#include <string>
+#include <utility>  // for pair
+
+#include <sysutils/SocketClient.h>
+
+class BandwidthController {
+public:
+    class TetherStats {
+    public:
+        TetherStats(void)
+                : rxBytes(-1), rxPackets(-1),
+                    txBytes(-1), txPackets(-1) {};
+        TetherStats(std::string intIfn, std::string extIfn,
+                int64_t rxB, int64_t rxP,
+                int64_t txB, int64_t txP)
+                        : intIface(intIfn), extIface(extIfn),
+                            rxBytes(rxB), rxPackets(rxP),
+                            txBytes(txB), txPackets(txP) {};
+        /* Internal interface. Same as NatController's notion. */
+        std::string intIface;
+        /* External interface. Same as NatController's notion. */
+        std::string extIface;
+        int64_t rxBytes, rxPackets;
+        int64_t txBytes, txPackets;
+        /*
+         * Allocates a new string representing this:
+         * intIface extIface rx_bytes rx_packets tx_bytes tx_packets
+         * The caller is responsible for free()'ing the returned ptr.
+         */
+        char *getStatsLine(void) const;
+    };
+
+    BandwidthController();
+
+    int setupIptablesHooks(void);
+
+    int enableBandwidthControl(bool force);
+    int disableBandwidthControl(void);
+
+    int setInterfaceSharedQuota(const char *iface, int64_t bytes);
+    int getInterfaceSharedQuota(int64_t *bytes);
+    int removeInterfaceSharedQuota(const char *iface);
+
+    int setInterfaceQuota(const char *iface, int64_t bytes);
+    int getInterfaceQuota(const char *iface, int64_t *bytes);
+    int removeInterfaceQuota(const char *iface);
+
+    int enableHappyBox(void);
+    int disableHappyBox(void);
+    int addNaughtyApps(int numUids, char *appUids[]);
+    int removeNaughtyApps(int numUids, char *appUids[]);
+    int addNiceApps(int numUids, char *appUids[]);
+    int removeNiceApps(int numUids, char *appUids[]);
+
+    int setGlobalAlert(int64_t bytes);
+    int removeGlobalAlert(void);
+    int setGlobalAlertInForwardChain(void);
+    int removeGlobalAlertInForwardChain(void);
+
+    int setSharedAlert(int64_t bytes);
+    int removeSharedAlert(void);
+
+    int setInterfaceAlert(const char *iface, int64_t bytes);
+    int removeInterfaceAlert(const char *iface);
+
+    /*
+     * For single pair of ifaces, stats should have ifaceIn and ifaceOut initialized.
+     * For all pairs, stats should have ifaceIn=ifaceOut="".
+     * Sends out to the cli the single stat (TetheringStatsReluts) or a list of stats
+     * (TetheringStatsListResult+CommandOkay).
+     * Error is to be handled on the outside.
+     * It results in an error if invoked and no tethering counter rules exist.
+     */
+    int getTetherStats(SocketClient *cli, TetherStats &stats, std::string &extraProcessingInfo);
+
+    static const char* LOCAL_INPUT;
+    static const char* LOCAL_FORWARD;
+    static const char* LOCAL_OUTPUT;
+    static const char* LOCAL_RAW_PREROUTING;
+    static const char* LOCAL_MANGLE_POSTROUTING;
+
+protected:
+    class QuotaInfo {
+    public:
+      QuotaInfo(std::string ifn, int64_t q, int64_t a)
+              : ifaceName(ifn), quota(q), alert(a) {};
+        std::string ifaceName;
+        int64_t quota;
+        int64_t alert;
+    };
+
+    enum IptIpVer { IptIpV4, IptIpV6 };
+    enum IptOp { IptOpInsert, IptOpReplace, IptOpDelete, IptOpAppend };
+    enum IptJumpOp { IptJumpReject, IptJumpReturn, IptJumpNoAdd };
+    enum SpecialAppOp { SpecialAppOpAdd, SpecialAppOpRemove };
+    enum QuotaType { QuotaUnique, QuotaShared };
+    enum RunCmdErrHandling { RunCmdFailureBad, RunCmdFailureOk };
+#if LOG_NDEBUG
+    enum IptFailureLog { IptFailShow, IptFailHide };
+#else
+    enum IptFailureLog { IptFailShow, IptFailHide = IptFailShow };
+#endif
+
+    int manipulateSpecialApps(int numUids, char *appStrUids[],
+                               const char *chain,
+                               std::list<int /*appUid*/> &specialAppUids,
+                               IptJumpOp jumpHandling, SpecialAppOp appOp);
+    int manipulateNaughtyApps(int numUids, char *appStrUids[], SpecialAppOp appOp);
+    int manipulateNiceApps(int numUids, char *appStrUids[], SpecialAppOp appOp);
+
+    int prepCostlyIface(const char *ifn, QuotaType quotaType);
+    int cleanupCostlyIface(const char *ifn, QuotaType quotaType);
+
+    std::string makeIptablesSpecialAppCmd(IptOp op, int uid, const char *chain);
+    std::string makeIptablesQuotaCmd(IptOp op, const char *costName, int64_t quota);
+
+    int runIptablesAlertCmd(IptOp op, const char *alertName, int64_t bytes);
+    int runIptablesAlertFwdCmd(IptOp op, const char *alertName, int64_t bytes);
+
+    /* Runs for both ipv4 and ipv6 iptables */
+    int runCommands(int numCommands, const char *commands[], RunCmdErrHandling cmdErrHandling);
+    /* Runs for both ipv4 and ipv6 iptables, appends -j REJECT --reject-with ...  */
+    static int runIpxtablesCmd(const char *cmd, IptJumpOp jumpHandling,
+                               IptFailureLog failureHandling = IptFailShow);
+    static int runIptablesCmd(const char *cmd, IptJumpOp jumpHandling, IptIpVer iptIpVer,
+                              IptFailureLog failureHandling = IptFailShow);
+
+
+    // Provides strncpy() + check overflow.
+    static int StrncpyAndCheck(char *buffer, const char *src, size_t buffSize);
+
+    int updateQuota(const char *alertName, int64_t bytes);
+
+    int setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes);
+    int removeCostlyAlert(const char *costName, int64_t *alertBytes);
+
+    /*
+     * stats should never have only intIface initialized. Other 3 combos are ok.
+     * fp should be a file to the apropriate FORWARD chain of iptables rules.
+     * extraProcessingInfo: contains raw parsed data, and error info.
+     * This strongly requires that setup of the rules is in a specific order:
+     *  in:intIface out:extIface
+     *  in:extIface out:intIface
+     * and the rules are grouped in pairs when more that one tethering was setup.
+     */
+    static int parseForwardChainStats(SocketClient *cli, const TetherStats filter, FILE *fp,
+                                      std::string &extraProcessingInfo);
+
+    /*
+     * Attempt to find the bw_costly_* tables that need flushing,
+     * and flush them.
+     * If doClean then remove the tables also.
+     * Deals with both ip4 and ip6 tables.
+     */
+    void flushExistingCostlyTables(bool doClean);
+    static void parseAndFlushCostlyTables(FILE *fp, bool doRemove);
+
+    /*
+     * Attempt to flush our tables.
+     * If doClean then remove them also.
+     * Deals with both ip4 and ip6 tables.
+     */
+    void flushCleanTables(bool doClean);
+
+    /*------------------*/
+
+    std::list<std::string> sharedQuotaIfaces;
+    int64_t sharedQuotaBytes;
+    int64_t sharedAlertBytes;
+    int64_t globalAlertBytes;
+    /*
+     * This tracks the number of tethers setup.
+     * The FORWARD chain is updated in the following cases:
+     *  - The 1st time a globalAlert is setup and there are tethers setup.
+     *  - Anytime a globalAlert is removed and there are tethers setup.
+     *  - The 1st tether is setup and there is a globalAlert active.
+     *  - The last tether is removed and there is a globalAlert active.
+     */
+    int globalAlertTetherCount;
+
+    std::list<QuotaInfo> quotaIfaces;
+    std::list<int /*appUid*/> naughtyAppUids;
+    std::list<int /*appUid*/> niceAppUids;
+
+private:
+    static const char *IPT_FLUSH_COMMANDS[];
+    static const char *IPT_CLEANUP_COMMANDS[];
+    static const char *IPT_SETUP_COMMANDS[];
+    static const char *IPT_BASIC_ACCOUNTING_COMMANDS[];
+
+    /* Alphabetical */
+    static const char ALERT_GLOBAL_NAME[];
+    static const int  MAX_CMD_ARGS;
+    static const int  MAX_CMD_LEN;
+    static const int  MAX_IFACENAME_LEN;
+    static const int  MAX_IPT_OUTPUT_LINE_LEN;
+};
+
+#endif
diff --git a/netd/server/ClatdController.cpp b/netd/server/ClatdController.cpp
new file mode 100644
index 0000000..348a0dd
--- /dev/null
+++ b/netd/server/ClatdController.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2008 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 <map>
+#include <string>
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#define LOG_TAG "ClatdController"
+#include <cutils/log.h>
+
+#include <resolv_netid.h>
+
+#include "NetdConstants.h"
+#include "ClatdController.h"
+#include "Fwmark.h"
+#include "NetdConstants.h"
+#include "NetworkController.h"
+
+static const char* kClatdPath = "/system/bin/clatd";
+
+ClatdController::ClatdController(NetworkController* controller)
+        : mNetCtrl(controller) {
+}
+
+ClatdController::~ClatdController() {
+}
+
+// Returns the PID of the clatd running on interface |interface|, or 0 if clatd is not running on
+// |interface|.
+pid_t ClatdController::getClatdPid(char* interface) {
+    auto it = mClatdPids.find(interface);
+    return (it == mClatdPids.end() ? 0 : it->second);
+}
+
+int ClatdController::startClatd(char* interface) {
+    pid_t pid = getClatdPid(interface);
+
+    if (pid != 0) {
+        ALOGE("clatd pid=%d already started on %s", pid, interface);
+        errno = EBUSY;
+        return -1;
+    }
+
+    // Pass in the interface, a netid to use for DNS lookups, and a fwmark for outgoing packets.
+    unsigned netId = mNetCtrl->getNetworkForInterface(interface);
+    if (netId == NETID_UNSET) {
+        ALOGE("interface %s not assigned to any netId", interface);
+        errno = ENODEV;
+        return -1;
+    }
+
+    char netIdString[UINT32_STRLEN];
+    snprintf(netIdString, sizeof(netIdString), "%u", netId);
+
+    Fwmark fwmark;
+    fwmark.netId = netId;
+    fwmark.explicitlySelected = true;
+    fwmark.protectedFromVpn = true;
+    fwmark.permission = PERMISSION_SYSTEM;
+
+    char fwmarkString[UINT32_HEX_STRLEN];
+    snprintf(fwmarkString, sizeof(fwmarkString), "0x%x", fwmark.intValue);
+
+    ALOGD("starting clatd on %s", interface);
+
+    std::string progname("clatd-");
+    progname += interface;
+
+    if ((pid = fork()) < 0) {
+        ALOGE("fork failed (%s)", strerror(errno));
+        return -1;
+    }
+
+    if (!pid) {
+        char *args[] = {
+            (char *) progname.c_str(),
+            (char *) "-i",
+            interface,
+            (char *) "-n",
+            netIdString,
+            (char *) "-m",
+            fwmarkString,
+            NULL
+        };
+
+        if (execv(kClatdPath, args)) {
+            ALOGE("execv failed (%s)", strerror(errno));
+            _exit(1);
+        }
+        ALOGE("Should never get here!");
+        _exit(1);
+    } else {
+        mClatdPids[interface] = pid;
+        ALOGD("clatd started on %s", interface);
+    }
+
+    return 0;
+}
+
+int ClatdController::stopClatd(char* interface) {
+    pid_t pid = getClatdPid(interface);
+
+    if (pid == 0) {
+        ALOGE("clatd already stopped");
+        return -1;
+    }
+
+    ALOGD("Stopping clatd pid=%d on %s", pid, interface);
+
+    kill(pid, SIGTERM);
+    waitpid(pid, NULL, 0);
+    mClatdPids.erase(interface);
+
+    ALOGD("clatd on %s stopped", interface);
+
+    return 0;
+}
+
+bool ClatdController::isClatdStarted(char* interface) {
+    pid_t waitpid_status;
+    pid_t pid = getClatdPid(interface);
+    if (pid == 0) {
+        return false;
+    }
+    waitpid_status = waitpid(pid, NULL, WNOHANG);
+    if (waitpid_status != 0) {
+        mClatdPids.erase(interface);  // child exited, don't call waitpid on it again
+    }
+    return waitpid_status == 0; // 0 while child is running
+}
diff --git a/netd/server/ClatdController.h b/netd/server/ClatdController.h
new file mode 100644
index 0000000..1985836
--- /dev/null
+++ b/netd/server/ClatdController.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _CLATD_CONTROLLER_H
+#define _CLATD_CONTROLLER_H
+
+#include <map>
+
+class NetworkController;
+
+class ClatdController {
+public:
+    explicit ClatdController(NetworkController* controller);
+    virtual ~ClatdController();
+
+    int startClatd(char *interface);
+    int stopClatd(char* interface);
+    bool isClatdStarted(char* interface);
+
+private:
+    NetworkController* const mNetCtrl;
+    std::map<std::string, pid_t> mClatdPids;
+    pid_t getClatdPid(char* interface);
+};
+
+#endif
diff --git a/netd/server/CleanSpec.mk b/netd/server/CleanSpec.mk
new file mode 100644
index 0000000..b84e1b6
--- /dev/null
+++ b/netd/server/CleanSpec.mk
@@ -0,0 +1,49 @@
+# Copyright (C) 2007 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.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list.  These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list.  E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/netd/server/CommandListener.cpp b/netd/server/CommandListener.cpp
new file mode 100644
index 0000000..47edd86
--- /dev/null
+++ b/netd/server/CommandListener.cpp
@@ -0,0 +1,1830 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+// #define LOG_NDEBUG 0
+
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <errno.h>
+#include <string.h>
+#include <linux/if.h>
+#include <resolv_netid.h>
+#include <resolv_params.h>
+
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+
+#define LOG_TAG "CommandListener"
+
+#include <cutils/log.h>
+#include <netutils/ifc.h>
+#include <sysutils/SocketClient.h>
+
+#include "CommandListener.h"
+#include "ResponseCode.h"
+#include "BandwidthController.h"
+#include "IdletimerController.h"
+#include "oem_iptables_hook.h"
+#include "NetdConstants.h"
+#include "FirewallController.h"
+#include "RouteController.h"
+#include "UidRanges.h"
+
+#include <string>
+#include <vector>
+
+namespace {
+
+const unsigned NUM_OEM_IDS = NetworkController::MAX_OEM_ID - NetworkController::MIN_OEM_ID + 1;
+
+Permission stringToPermission(const char* arg) {
+    if (!strcmp(arg, "NETWORK")) {
+        return PERMISSION_NETWORK;
+    }
+    if (!strcmp(arg, "SYSTEM")) {
+        return PERMISSION_SYSTEM;
+    }
+    return PERMISSION_NONE;
+}
+
+unsigned stringToNetId(const char* arg) {
+    if (!strcmp(arg, "local")) {
+        return NetworkController::LOCAL_NET_ID;
+    }
+    // OEM NetIds are "oem1", "oem2", .., "oem50".
+    if (!strncmp(arg, "oem", 3)) {
+        unsigned n = strtoul(arg + 3, NULL, 0);
+        if (1 <= n && n <= NUM_OEM_IDS) {
+            return NetworkController::MIN_OEM_ID + n;
+        }
+        return NETID_UNSET;
+    }
+    // strtoul() returns 0 on errors, which is fine because 0 is an invalid netId.
+    return strtoul(arg, NULL, 0);
+}
+
+}  // namespace
+
+NetworkController *CommandListener::sNetCtrl = NULL;
+TetherController *CommandListener::sTetherCtrl = NULL;
+NatController *CommandListener::sNatCtrl = NULL;
+PppController *CommandListener::sPppCtrl = NULL;
+SoftapController *CommandListener::sSoftapCtrl = NULL;
+BandwidthController * CommandListener::sBandwidthCtrl = NULL;
+IdletimerController * CommandListener::sIdletimerCtrl = NULL;
+InterfaceController *CommandListener::sInterfaceCtrl = NULL;
+ResolverController *CommandListener::sResolverCtrl = NULL;
+FirewallController *CommandListener::sFirewallCtrl = NULL;
+ClatdController *CommandListener::sClatdCtrl = NULL;
+StrictController *CommandListener::sStrictCtrl = NULL;
+
+/**
+ * List of module chains to be created, along with explicit ordering. ORDERING
+ * IS CRITICAL, AND SHOULD BE TRIPLE-CHECKED WITH EACH CHANGE.
+ */
+static const char* FILTER_INPUT[] = {
+        // Bandwidth should always be early in input chain, to make sure we
+        // correctly count incoming traffic against data plan.
+        BandwidthController::LOCAL_INPUT,
+        FirewallController::LOCAL_INPUT,
+        NULL,
+};
+
+static const char* FILTER_FORWARD[] = {
+        OEM_IPTABLES_FILTER_FORWARD,
+        FirewallController::LOCAL_FORWARD,
+        BandwidthController::LOCAL_FORWARD,
+        NatController::LOCAL_FORWARD,
+        NULL,
+};
+
+static const char* FILTER_OUTPUT[] = {
+        OEM_IPTABLES_FILTER_OUTPUT,
+        FirewallController::LOCAL_OUTPUT,
+        StrictController::LOCAL_OUTPUT,
+        BandwidthController::LOCAL_OUTPUT,
+        NULL,
+};
+
+static const char* RAW_PREROUTING[] = {
+        BandwidthController::LOCAL_RAW_PREROUTING,
+        IdletimerController::LOCAL_RAW_PREROUTING,
+        NULL,
+};
+
+static const char* MANGLE_POSTROUTING[] = {
+        BandwidthController::LOCAL_MANGLE_POSTROUTING,
+        IdletimerController::LOCAL_MANGLE_POSTROUTING,
+        NULL,
+};
+
+static const char* MANGLE_FORWARD[] = {
+        NatController::LOCAL_MANGLE_FORWARD,
+        NULL,
+};
+
+static const char* NAT_PREROUTING[] = {
+        OEM_IPTABLES_NAT_PREROUTING,
+        NULL,
+};
+
+static const char* NAT_POSTROUTING[] = {
+        NatController::LOCAL_NAT_POSTROUTING,
+        NULL,
+};
+
+static void createChildChains(IptablesTarget target, const char* table, const char* parentChain,
+        const char** childChains) {
+    const char** childChain = childChains;
+    do {
+        // Order is important:
+        // -D to delete any pre-existing jump rule (removes references
+        //    that would prevent -X from working)
+        // -F to flush any existing chain
+        // -X to delete any existing chain
+        // -N to create the chain
+        // -A to append the chain to parent
+
+        execIptablesSilently(target, "-t", table, "-D", parentChain, "-j", *childChain, NULL);
+        execIptablesSilently(target, "-t", table, "-F", *childChain, NULL);
+        execIptablesSilently(target, "-t", table, "-X", *childChain, NULL);
+        execIptables(target, "-t", table, "-N", *childChain, NULL);
+        execIptables(target, "-t", table, "-A", parentChain, "-j", *childChain, NULL);
+    } while (*(++childChain) != NULL);
+}
+
+CommandListener::CommandListener() :
+                 FrameworkListener("netd", true) {
+    registerCmd(new InterfaceCmd());
+    registerCmd(new IpFwdCmd());
+    registerCmd(new TetherCmd());
+    registerCmd(new NatCmd());
+    registerCmd(new ListTtysCmd());
+    registerCmd(new PppdCmd());
+    registerCmd(new SoftapCmd());
+    registerCmd(new BandwidthControlCmd());
+    registerCmd(new IdletimerControlCmd());
+    registerCmd(new ResolverCmd());
+    registerCmd(new FirewallCmd());
+    registerCmd(new ClatdCmd());
+    registerCmd(new NetworkCommand());
+    registerCmd(new StrictCmd());
+
+    if (!sNetCtrl)
+        sNetCtrl = new NetworkController();
+    if (!sTetherCtrl)
+        sTetherCtrl = new TetherController();
+    if (!sNatCtrl)
+        sNatCtrl = new NatController();
+    if (!sPppCtrl)
+        sPppCtrl = new PppController();
+    if (!sSoftapCtrl)
+        sSoftapCtrl = new SoftapController();
+    if (!sBandwidthCtrl)
+        sBandwidthCtrl = new BandwidthController();
+    if (!sIdletimerCtrl)
+        sIdletimerCtrl = new IdletimerController();
+    if (!sResolverCtrl)
+        sResolverCtrl = new ResolverController();
+    if (!sFirewallCtrl)
+        sFirewallCtrl = new FirewallController();
+    if (!sInterfaceCtrl)
+        sInterfaceCtrl = new InterfaceController();
+    if (!sClatdCtrl)
+        sClatdCtrl = new ClatdController(sNetCtrl);
+    if (!sStrictCtrl)
+        sStrictCtrl = new StrictController();
+
+    /*
+     * This is the only time we touch top-level chains in iptables; controllers
+     * should only mutate rules inside of their children chains, as created by
+     * the constants above.
+     *
+     * Modules should never ACCEPT packets (except in well-justified cases);
+     * they should instead defer to any remaining modules using RETURN, or
+     * otherwise DROP/REJECT.
+     */
+
+    // Create chains for children modules
+    createChildChains(V4V6, "filter", "INPUT", FILTER_INPUT);
+    createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD);
+    createChildChains(V4V6, "filter", "OUTPUT", FILTER_OUTPUT);
+    createChildChains(V4V6, "raw", "PREROUTING", RAW_PREROUTING);
+    createChildChains(V4V6, "mangle", "POSTROUTING", MANGLE_POSTROUTING);
+    createChildChains(V4, "mangle", "FORWARD", MANGLE_FORWARD);
+    createChildChains(V4, "nat", "PREROUTING", NAT_PREROUTING);
+    createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING);
+
+    // Let each module setup their child chains
+    setupOemIptablesHook();
+
+    /* When enabled, DROPs all packets except those matching rules. */
+    sFirewallCtrl->setupIptablesHooks();
+
+    /* Does DROPs in FORWARD by default */
+    sNatCtrl->setupIptablesHooks();
+    /*
+     * Does REJECT in INPUT, OUTPUT. Does counting also.
+     * No DROP/REJECT allowed later in netfilter-flow hook order.
+     */
+    sBandwidthCtrl->setupIptablesHooks();
+    /*
+     * Counts in nat: PREROUTING, POSTROUTING.
+     * No DROP/REJECT allowed later in netfilter-flow hook order.
+     */
+    sIdletimerCtrl->setupIptablesHooks();
+
+    sBandwidthCtrl->enableBandwidthControl(false);
+
+    if (int ret = RouteController::Init(NetworkController::LOCAL_NET_ID)) {
+        ALOGE("failed to initialize RouteController (%s)", strerror(-ret));
+    }
+}
+
+CommandListener::InterfaceCmd::InterfaceCmd() :
+                 NetdCommand("interface") {
+}
+
+int CommandListener::InterfaceCmd::runCommand(SocketClient *cli,
+                                                      int argc, char **argv) {
+    if (argc < 2) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+        return 0;
+    }
+
+    if (!strcmp(argv[1], "list")) {
+        DIR *d;
+        struct dirent *de;
+
+        if (!(d = opendir("/sys/class/net"))) {
+            cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true);
+            return 0;
+        }
+
+        while((de = readdir(d))) {
+            if (de->d_name[0] == '.')
+                continue;
+            cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false);
+        }
+        closedir(d);
+        cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false);
+        return 0;
+    } else {
+        /*
+         * These commands take a minimum of 3 arguments
+         */
+        if (argc < 3) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+            return 0;
+        }
+
+        if (!strcmp(argv[1], "getcfg")) {
+            struct in_addr addr;
+            int prefixLength;
+            unsigned char hwaddr[6];
+            unsigned flags = 0;
+
+            ifc_init();
+            memset(hwaddr, 0, sizeof(hwaddr));
+
+            if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) {
+                cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true);
+                ifc_close();
+                return 0;
+            }
+
+            if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) {
+                ALOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno));
+            }
+
+            char *addr_s = strdup(inet_ntoa(addr));
+            const char *updown, *brdcst, *loopbk, *ppp, *running, *multi;
+
+            updown =  (flags & IFF_UP)           ? "up" : "down";
+            brdcst =  (flags & IFF_BROADCAST)    ? " broadcast" : "";
+            loopbk =  (flags & IFF_LOOPBACK)     ? " loopback" : "";
+            ppp =     (flags & IFF_POINTOPOINT)  ? " point-to-point" : "";
+            running = (flags & IFF_RUNNING)      ? " running" : "";
+            multi =   (flags & IFF_MULTICAST)    ? " multicast" : "";
+
+            char *flag_s;
+
+            asprintf(&flag_s, "%s%s%s%s%s%s", updown, brdcst, loopbk, ppp, running, multi);
+
+            char *msg = NULL;
+            asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s",
+                     hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5],
+                     addr_s, prefixLength, flag_s);
+
+            cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false);
+
+            free(addr_s);
+            free(flag_s);
+            free(msg);
+
+            ifc_close();
+            return 0;
+        } else if (!strcmp(argv[1], "setcfg")) {
+            // arglist: iface [addr prefixLength] flags
+            if (argc < 4) {
+                cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+                return 0;
+            }
+            ALOGD("Setting iface cfg");
+
+            struct in_addr addr;
+            int index = 5;
+
+            ifc_init();
+
+            if (!inet_aton(argv[3], &addr)) {
+                // Handle flags only case
+                index = 3;
+            } else {
+                if (ifc_set_addr(argv[2], addr.s_addr)) {
+                    cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true);
+                    ifc_close();
+                    return 0;
+                }
+
+                // Set prefix length on a non zero address
+                if (addr.s_addr != 0 && ifc_set_prefixLength(argv[2], atoi(argv[4]))) {
+                   cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true);
+                   ifc_close();
+                   return 0;
+               }
+            }
+
+            /* Process flags */
+            for (int i = index; i < argc; i++) {
+                char *flag = argv[i];
+                if (!strcmp(flag, "up")) {
+                    ALOGD("Trying to bring up %s", argv[2]);
+                    if (ifc_up(argv[2])) {
+                        ALOGE("Error upping interface");
+                        cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true);
+                        ifc_close();
+                        return 0;
+                    }
+                } else if (!strcmp(flag, "down")) {
+                    ALOGD("Trying to bring down %s", argv[2]);
+                    if (ifc_down(argv[2])) {
+                        ALOGE("Error downing interface");
+                        cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true);
+                        ifc_close();
+                        return 0;
+                    }
+                } else if (!strcmp(flag, "broadcast")) {
+                    // currently ignored
+                } else if (!strcmp(flag, "multicast")) {
+                    // currently ignored
+                } else if (!strcmp(flag, "running")) {
+                    // currently ignored
+                } else if (!strcmp(flag, "loopback")) {
+                    // currently ignored
+                } else if (!strcmp(flag, "point-to-point")) {
+                    // currently ignored
+                } else {
+                    cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false);
+                    ifc_close();
+                    return 0;
+                }
+            }
+
+            cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false);
+            ifc_close();
+            return 0;
+        } else if (!strcmp(argv[1], "clearaddrs")) {
+            // arglist: iface
+            ALOGD("Clearing all IP addresses on %s", argv[2]);
+
+            ifc_clear_addresses(argv[2]);
+
+            cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false);
+            return 0;
+        } else if (!strcmp(argv[1], "ipv6privacyextensions")) {
+            if (argc != 4) {
+                cli->sendMsg(ResponseCode::CommandSyntaxError,
+                        "Usage: interface ipv6privacyextensions <interface> <enable|disable>",
+                        false);
+                return 0;
+            }
+            int enable = !strncmp(argv[3], "enable", 7);
+            if (sInterfaceCtrl->setIPv6PrivacyExtensions(argv[2], enable) == 0) {
+                cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false);
+            } else {
+                cli->sendMsg(ResponseCode::OperationFailed,
+                        "Failed to set ipv6 privacy extensions", true);
+            }
+            return 0;
+        } else if (!strcmp(argv[1], "ipv6")) {
+            if (argc != 4) {
+                cli->sendMsg(ResponseCode::CommandSyntaxError,
+                        "Usage: interface ipv6 <interface> <enable|disable>",
+                        false);
+                return 0;
+            }
+
+            int enable = !strncmp(argv[3], "enable", 7);
+            if (sInterfaceCtrl->setEnableIPv6(argv[2], enable) == 0) {
+                cli->sendMsg(ResponseCode::CommandOkay, "IPv6 state changed", false);
+            } else {
+                cli->sendMsg(ResponseCode::OperationFailed,
+                        "Failed to change IPv6 state", true);
+            }
+            return 0;
+        } else if (!strcmp(argv[1], "ipv6ndoffload")) {
+            if (argc != 4) {
+                cli->sendMsg(ResponseCode::CommandSyntaxError,
+                        "Usage: interface ipv6ndoffload <interface> <enable|disable>",
+                        false);
+                return 0;
+            }
+            int enable = !strncmp(argv[3], "enable", 7);
+            if (sInterfaceCtrl->setIPv6NdOffload(argv[2], enable) == 0) {
+                cli->sendMsg(ResponseCode::CommandOkay, "IPv6 ND offload changed", false);
+            } else {
+                cli->sendMsg(ResponseCode::OperationFailed,
+                        "Failed to change IPv6 ND offload state", true);
+            }
+            return 0;
+        } else if (!strcmp(argv[1], "setmtu")) {
+            if (argc != 4) {
+                cli->sendMsg(ResponseCode::CommandSyntaxError,
+                        "Usage: interface setmtu <interface> <val>", false);
+                return 0;
+            }
+            if (sInterfaceCtrl->setMtu(argv[2], argv[3]) == 0) {
+                cli->sendMsg(ResponseCode::CommandOkay, "MTU changed", false);
+            } else {
+                cli->sendMsg(ResponseCode::OperationFailed,
+                        "Failed to set MTU", true);
+            }
+            return 0;
+        } else {
+            cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false);
+            return 0;
+        }
+    }
+    return 0;
+}
+
+
+CommandListener::ListTtysCmd::ListTtysCmd() :
+                 NetdCommand("list_ttys") {
+}
+
+int CommandListener::ListTtysCmd::runCommand(SocketClient *cli,
+                                             int /* argc */, char ** /* argv */) {
+    TtyCollection *tlist = sPppCtrl->getTtyList();
+    TtyCollection::iterator it;
+
+    for (it = tlist->begin(); it != tlist->end(); ++it) {
+        cli->sendMsg(ResponseCode::TtyListResult, *it, false);
+    }
+
+    cli->sendMsg(ResponseCode::CommandOkay, "Ttys listed.", false);
+    return 0;
+}
+
+CommandListener::IpFwdCmd::IpFwdCmd() :
+                 NetdCommand("ipfwd") {
+}
+
+int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, int argc, char **argv) {
+    bool matched = false;
+    bool success;
+
+    if (argc == 2) {
+        //   0     1
+        // ipfwd status
+        if (!strcmp(argv[1], "status")) {
+            char *tmp = NULL;
+
+            asprintf(&tmp, "Forwarding %s",
+                     ((sTetherCtrl->forwardingRequestCount() > 0) ? "enabled" : "disabled"));
+            cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false);
+            free(tmp);
+            return 0;
+        }
+    } else if (argc == 3) {
+        //  0      1         2
+        // ipfwd enable  <requester>
+        // ipfwd disable <requester>
+        if (!strcmp(argv[1], "enable")) {
+            matched = true;
+            success = sTetherCtrl->enableForwarding(argv[2]);
+        } else if (!strcmp(argv[1], "disable")) {
+            matched = true;
+            success = sTetherCtrl->disableForwarding(argv[2]);
+        }
+    } else if (argc == 4) {
+        //  0      1      2     3
+        // ipfwd  add   wlan0 dummy0
+        // ipfwd remove wlan0 dummy0
+        int ret = 0;
+        if (!strcmp(argv[1], "add")) {
+            matched = true;
+            ret = RouteController::enableTethering(argv[2], argv[3]);
+        } else if (!strcmp(argv[1], "remove")) {
+            matched = true;
+            ret = RouteController::disableTethering(argv[2], argv[3]);
+        }
+        success = (ret == 0);
+        errno = -ret;
+    }
+
+    if (!matched) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false);
+        return 0;
+    }
+
+    if (success) {
+        cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false);
+    } else {
+        cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true);
+    }
+    return 0;
+}
+
+CommandListener::TetherCmd::TetherCmd() :
+                 NetdCommand("tether") {
+}
+
+int CommandListener::TetherCmd::runCommand(SocketClient *cli,
+                                                      int argc, char **argv) {
+    int rc = 0;
+
+    if (argc < 2) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+        return 0;
+    }
+
+    if (!strcmp(argv[1], "stop")) {
+        rc = sTetherCtrl->stopTethering();
+    } else if (!strcmp(argv[1], "status")) {
+        char *tmp = NULL;
+
+        asprintf(&tmp, "Tethering services %s",
+                 (sTetherCtrl->isTetheringStarted() ? "started" : "stopped"));
+        cli->sendMsg(ResponseCode::TetherStatusResult, tmp, false);
+        free(tmp);
+        return 0;
+    } else if (argc == 3) {
+        if (!strcmp(argv[1], "interface") && !strcmp(argv[2], "list")) {
+            InterfaceCollection *ilist = sTetherCtrl->getTetheredInterfaceList();
+            InterfaceCollection::iterator it;
+            for (it = ilist->begin(); it != ilist->end(); ++it) {
+                cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false);
+            }
+        } else if (!strcmp(argv[1], "dns") && !strcmp(argv[2], "list")) {
+            char netIdStr[UINT32_STRLEN];
+            snprintf(netIdStr, sizeof(netIdStr), "%u", sTetherCtrl->getDnsNetId());
+            cli->sendMsg(ResponseCode::TetherDnsFwdNetIdResult, netIdStr, false);
+
+            NetAddressCollection *dlist = sTetherCtrl->getDnsForwarders();
+            NetAddressCollection::iterator it;
+
+            for (it = dlist->begin(); it != dlist->end(); ++it) {
+                cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, inet_ntoa(*it), false);
+            }
+        }
+    } else {
+        /*
+         * These commands take a minimum of 4 arguments
+         */
+        if (argc < 4) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+            return 0;
+        }
+
+        if (!strcmp(argv[1], "start")) {
+            if (argc % 2 == 1) {
+                cli->sendMsg(ResponseCode::CommandSyntaxError, "Bad number of arguments", false);
+                return 0;
+            }
+
+            int num_addrs = argc - 2;
+            int arg_index = 2;
+            int array_index = 0;
+            in_addr *addrs = (in_addr *)malloc(sizeof(in_addr) * num_addrs);
+            while (array_index < num_addrs) {
+                if (!inet_aton(argv[arg_index++], &(addrs[array_index++]))) {
+                    cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false);
+                    free(addrs);
+                    return 0;
+                }
+            }
+            rc = sTetherCtrl->startTethering(num_addrs, addrs);
+            free(addrs);
+        } else if (!strcmp(argv[1], "interface")) {
+            if (!strcmp(argv[2], "add")) {
+                rc = sTetherCtrl->tetherInterface(argv[3]);
+            } else if (!strcmp(argv[2], "remove")) {
+                rc = sTetherCtrl->untetherInterface(argv[3]);
+            /* else if (!strcmp(argv[2], "list")) handled above */
+            } else {
+                cli->sendMsg(ResponseCode::CommandParameterError,
+                             "Unknown tether interface operation", false);
+                return 0;
+            }
+        } else if (!strcmp(argv[1], "dns")) {
+            if (!strcmp(argv[2], "set")) {
+                if (argc < 5) {
+                    cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+                    return 0;
+                }
+                unsigned netId = stringToNetId(argv[3]);
+                rc = sTetherCtrl->setDnsForwarders(netId, &argv[4], argc - 4);
+            /* else if (!strcmp(argv[2], "list")) handled above */
+            } else {
+                cli->sendMsg(ResponseCode::CommandParameterError,
+                             "Unknown tether interface operation", false);
+                return 0;
+            }
+        } else {
+            cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown tether cmd", false);
+            return 0;
+        }
+    }
+
+    if (!rc) {
+        cli->sendMsg(ResponseCode::CommandOkay, "Tether operation succeeded", false);
+    } else {
+        cli->sendMsg(ResponseCode::OperationFailed, "Tether operation failed", true);
+    }
+
+    return 0;
+}
+
+CommandListener::NatCmd::NatCmd() :
+                 NetdCommand("nat") {
+}
+
+int CommandListener::NatCmd::runCommand(SocketClient *cli,
+                                                      int argc, char **argv) {
+    int rc = 0;
+
+    if (argc < 5) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+        return 0;
+    }
+
+    //  0     1       2        3
+    // nat  enable intiface extiface
+    // nat disable intiface extiface
+    if (!strcmp(argv[1], "enable") && argc >= 4) {
+        rc = sNatCtrl->enableNat(argv[2], argv[3]);
+        if(!rc) {
+            /* Ignore ifaces for now. */
+            rc = sBandwidthCtrl->setGlobalAlertInForwardChain();
+        }
+    } else if (!strcmp(argv[1], "disable") && argc >= 4) {
+        /* Ignore ifaces for now. */
+        rc = sBandwidthCtrl->removeGlobalAlertInForwardChain();
+        rc |= sNatCtrl->disableNat(argv[2], argv[3]);
+    } else {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown nat cmd", false);
+        return 0;
+    }
+
+    if (!rc) {
+        cli->sendMsg(ResponseCode::CommandOkay, "Nat operation succeeded", false);
+    } else {
+        cli->sendMsg(ResponseCode::OperationFailed, "Nat operation failed", true);
+    }
+
+    return 0;
+}
+
+CommandListener::PppdCmd::PppdCmd() :
+                 NetdCommand("pppd") {
+}
+
+int CommandListener::PppdCmd::runCommand(SocketClient *cli,
+                                                      int argc, char **argv) {
+    int rc = 0;
+
+    if (argc < 3) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+        return 0;
+    }
+
+    if (!strcmp(argv[1], "attach")) {
+        struct in_addr l, r, dns1, dns2;
+
+        memset(&dns1, 0, sizeof(struct in_addr));
+        memset(&dns2, 0, sizeof(struct in_addr));
+
+        if (!inet_aton(argv[3], &l)) {
+            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid local address", false);
+            return 0;
+        }
+        if (!inet_aton(argv[4], &r)) {
+            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid remote address", false);
+            return 0;
+        }
+        if ((argc > 3) && (!inet_aton(argv[5], &dns1))) {
+            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns1 address", false);
+            return 0;
+        }
+        if ((argc > 4) && (!inet_aton(argv[6], &dns2))) {
+            cli->sendMsg(ResponseCode::CommandParameterError, "Invalid dns2 address", false);
+            return 0;
+        }
+        rc = sPppCtrl->attachPppd(argv[2], l, r, dns1, dns2);
+    } else if (!strcmp(argv[1], "detach")) {
+        rc = sPppCtrl->detachPppd(argv[2]);
+    } else {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown pppd cmd", false);
+        return 0;
+    }
+
+    if (!rc) {
+        cli->sendMsg(ResponseCode::CommandOkay, "Pppd operation succeeded", false);
+    } else {
+        cli->sendMsg(ResponseCode::OperationFailed, "Pppd operation failed", true);
+    }
+
+    return 0;
+}
+
+CommandListener::SoftapCmd::SoftapCmd() :
+                 NetdCommand("softap") {
+}
+
+int CommandListener::SoftapCmd::runCommand(SocketClient *cli,
+                                        int argc, char **argv) {
+    int rc = ResponseCode::SoftapStatusResult;
+    char *retbuf = NULL;
+
+    if (sSoftapCtrl == NULL) {
+      cli->sendMsg(ResponseCode::ServiceStartFailed, "SoftAP is not available", false);
+      return -1;
+    }
+    if (argc < 2) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError,
+                     "Missing argument in a SoftAP command", false);
+        return 0;
+    }
+
+    if (!strcmp(argv[1], "startap")) {
+        rc = sSoftapCtrl->startSoftap();
+    } else if (!strcmp(argv[1], "stopap")) {
+        rc = sSoftapCtrl->stopSoftap();
+    } else if (!strcmp(argv[1], "fwreload")) {
+        rc = sSoftapCtrl->fwReloadSoftap(argc, argv);
+    } else if (!strcmp(argv[1], "status")) {
+        asprintf(&retbuf, "Softap service %s running",
+                 (sSoftapCtrl->isSoftapStarted() ? "is" : "is not"));
+        cli->sendMsg(rc, retbuf, false);
+        free(retbuf);
+        return 0;
+    } else if (!strcmp(argv[1], "set")) {
+        rc = sSoftapCtrl->setSoftap(argc, argv);
+    } else {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unrecognized SoftAP command", false);
+        return 0;
+    }
+
+    if (rc >= 400 && rc < 600)
+      cli->sendMsg(rc, "SoftAP command has failed", false);
+    else
+      cli->sendMsg(rc, "Ok", false);
+
+    return 0;
+}
+
+CommandListener::ResolverCmd::ResolverCmd() :
+        NetdCommand("resolver") {
+}
+
+int CommandListener::ResolverCmd::runCommand(SocketClient *cli, int argc, char **margv) {
+    int rc = 0;
+    const char **argv = const_cast<const char **>(margv);
+
+    if (argc < 3) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Resolver missing arguments", false);
+        return 0;
+    }
+
+    unsigned netId = stringToNetId(argv[2]);
+    // TODO: Consider making NetworkController.isValidNetwork() public
+    // and making that check here.
+
+    if (!strcmp(argv[1], "setnetdns")) {
+        // "resolver setnetdns <netId> <domains> <dns servers> [<params>]"
+        if (!parseAndExecuteSetNetDns(netId, argc, argv)) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                    "Wrong number of or invalid arguments to resolver setnetdns", false);
+            return 0;
+        }
+    } else if (!strcmp(argv[1], "clearnetdns")) { // "resolver clearnetdns <netId>"
+        if (argc == 3) {
+            rc = sResolverCtrl->clearDnsServers(netId);
+        } else {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                    "Wrong number of arguments to resolver clearnetdns", false);
+            return 0;
+        }
+    } else if (!strcmp(argv[1], "flushnet")) { // "resolver flushnet <netId>"
+        if (argc == 3) {
+            rc = sResolverCtrl->flushDnsCache(netId);
+        } else {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                    "Wrong number of arguments to resolver flushnet", false);
+            return 0;
+        }
+    } else {
+        cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false);
+        return 0;
+    }
+
+    if (!rc) {
+        cli->sendMsg(ResponseCode::CommandOkay, "Resolver command succeeded", false);
+    } else {
+        cli->sendMsg(ResponseCode::OperationFailed, "Resolver command failed", true);
+    }
+
+    return 0;
+}
+
+bool CommandListener::ResolverCmd::parseAndExecuteSetNetDns(int netId, int argc,
+        const char** argv) {
+    // "resolver setnetdns <netId> <domains> <dns1> [<dns2> ...] [--params <params>]"
+    // TODO: This code has to be replaced by a Binder call ASAP
+    if (argc < 5) {
+        return false;
+    }
+    int end = argc;
+    __res_params params;
+    const __res_params* paramsPtr = nullptr;
+    if (end > 6 && !strcmp(argv[end - 2], "--params")) {
+        const char* paramsStr = argv[end - 1];
+        end -= 2;
+        if (sscanf(paramsStr, "%hu %hhu %hhu %hhu", &params.sample_validity,
+                &params.success_threshold, &params.min_samples, &params.max_samples) != 4) {
+            return false;
+        }
+        paramsPtr = &params;
+    }
+    return sResolverCtrl->setDnsServers(netId, argv[3], &argv[4], end - 4, paramsPtr) == 0;
+}
+
+CommandListener::BandwidthControlCmd::BandwidthControlCmd() :
+    NetdCommand("bandwidth") {
+}
+
+void CommandListener::BandwidthControlCmd::sendGenericSyntaxError(SocketClient *cli, const char *usageMsg) {
+    char *msg;
+    asprintf(&msg, "Usage: bandwidth %s", usageMsg);
+    cli->sendMsg(ResponseCode::CommandSyntaxError, msg, false);
+    free(msg);
+}
+
+void CommandListener::BandwidthControlCmd::sendGenericOkFail(SocketClient *cli, int cond) {
+    if (!cond) {
+        cli->sendMsg(ResponseCode::CommandOkay, "Bandwidth command succeeeded", false);
+    } else {
+        cli->sendMsg(ResponseCode::OperationFailed, "Bandwidth command failed", false);
+    }
+}
+
+void CommandListener::BandwidthControlCmd::sendGenericOpFailed(SocketClient *cli, const char *errMsg) {
+    cli->sendMsg(ResponseCode::OperationFailed, errMsg, false);
+}
+
+int CommandListener::BandwidthControlCmd::runCommand(SocketClient *cli, int argc, char **argv) {
+    if (argc < 2) {
+        sendGenericSyntaxError(cli, "<cmds> <args...>");
+        return 0;
+    }
+
+    ALOGV("bwctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]);
+
+    if (!strcmp(argv[1], "enable")) {
+        int rc = sBandwidthCtrl->enableBandwidthControl(true);
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "disable")) {
+        int rc = sBandwidthCtrl->disableBandwidthControl();
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "removequota") || !strcmp(argv[1], "rq")) {
+        if (argc != 3) {
+            sendGenericSyntaxError(cli, "removequota <interface>");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[2]);
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "getquota") || !strcmp(argv[1], "gq")) {
+        int64_t bytes;
+        if (argc != 2) {
+            sendGenericSyntaxError(cli, "getquota");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->getInterfaceSharedQuota(&bytes);
+        if (rc) {
+            sendGenericOpFailed(cli, "Failed to get quota");
+            return 0;
+        }
+
+        char *msg;
+        asprintf(&msg, "%" PRId64, bytes);
+        cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false);
+        free(msg);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "getiquota") || !strcmp(argv[1], "giq")) {
+        int64_t bytes;
+        if (argc != 3) {
+            sendGenericSyntaxError(cli, "getiquota <iface>");
+            return 0;
+        }
+
+        int rc = sBandwidthCtrl->getInterfaceQuota(argv[2], &bytes);
+        if (rc) {
+            sendGenericOpFailed(cli, "Failed to get quota");
+            return 0;
+        }
+        char *msg;
+        asprintf(&msg, "%" PRId64, bytes);
+        cli->sendMsg(ResponseCode::QuotaCounterResult, msg, false);
+        free(msg);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "setquota") || !strcmp(argv[1], "sq")) {
+        if (argc != 4) {
+            sendGenericSyntaxError(cli, "setquota <interface> <bytes>");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[2], atoll(argv[3]));
+        sendGenericOkFail(cli, rc);
+        return 0;
+    }
+    if (!strcmp(argv[1], "setquotas") || !strcmp(argv[1], "sqs")) {
+        int rc;
+        if (argc < 4) {
+            sendGenericSyntaxError(cli, "setquotas <bytes> <interface> ...");
+            return 0;
+        }
+
+        for (int q = 3; argc >= 4; q++, argc--) {
+            rc = sBandwidthCtrl->setInterfaceSharedQuota(argv[q], atoll(argv[2]));
+            if (rc) {
+                char *msg;
+                asprintf(&msg, "bandwidth setquotas %s %s failed", argv[2], argv[q]);
+                cli->sendMsg(ResponseCode::OperationFailed,
+                             msg, false);
+                free(msg);
+                return 0;
+            }
+        }
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "removequotas") || !strcmp(argv[1], "rqs")) {
+        int rc;
+        if (argc < 3) {
+            sendGenericSyntaxError(cli, "removequotas <interface> ...");
+            return 0;
+        }
+
+        for (int q = 2; argc >= 3; q++, argc--) {
+            rc = sBandwidthCtrl->removeInterfaceSharedQuota(argv[q]);
+            if (rc) {
+                char *msg;
+                asprintf(&msg, "bandwidth removequotas %s failed", argv[q]);
+                cli->sendMsg(ResponseCode::OperationFailed,
+                             msg, false);
+                free(msg);
+                return 0;
+            }
+        }
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "removeiquota") || !strcmp(argv[1], "riq")) {
+        if (argc != 3) {
+            sendGenericSyntaxError(cli, "removeiquota <interface>");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->removeInterfaceQuota(argv[2]);
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "setiquota") || !strcmp(argv[1], "siq")) {
+        if (argc != 4) {
+            sendGenericSyntaxError(cli, "setiquota <interface> <bytes>");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->setInterfaceQuota(argv[2], atoll(argv[3]));
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "addnaughtyapps") || !strcmp(argv[1], "ana")) {
+        if (argc < 3) {
+            sendGenericSyntaxError(cli, "addnaughtyapps <appUid> ...");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->addNaughtyApps(argc - 2, argv + 2);
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+
+    }
+    if (!strcmp(argv[1], "removenaughtyapps") || !strcmp(argv[1], "rna")) {
+        if (argc < 3) {
+            sendGenericSyntaxError(cli, "removenaughtyapps <appUid> ...");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->removeNaughtyApps(argc - 2, argv + 2);
+        sendGenericOkFail(cli, rc);
+        return 0;
+    }
+    if (!strcmp(argv[1], "happybox")) {
+        if (argc < 3) {
+            sendGenericSyntaxError(cli, "happybox (enable | disable)");
+            return 0;
+        }
+        if (!strcmp(argv[2], "enable")) {
+            int rc = sBandwidthCtrl->enableHappyBox();
+            sendGenericOkFail(cli, rc);
+            return 0;
+
+        }
+        if (!strcmp(argv[2], "disable")) {
+            int rc = sBandwidthCtrl->disableHappyBox();
+            sendGenericOkFail(cli, rc);
+            return 0;
+        }
+        sendGenericSyntaxError(cli, "happybox (enable | disable)");
+        return 0;
+    }
+    if (!strcmp(argv[1], "addniceapps") || !strcmp(argv[1], "aha")) {
+        if (argc < 3) {
+            sendGenericSyntaxError(cli, "addniceapps <appUid> ...");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->addNiceApps(argc - 2, argv + 2);
+        sendGenericOkFail(cli, rc);
+        return 0;
+    }
+    if (!strcmp(argv[1], "removeniceapps") || !strcmp(argv[1], "rha")) {
+        if (argc < 3) {
+            sendGenericSyntaxError(cli, "removeniceapps <appUid> ...");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->removeNiceApps(argc - 2, argv + 2);
+        sendGenericOkFail(cli, rc);
+        return 0;
+    }
+    if (!strcmp(argv[1], "setglobalalert") || !strcmp(argv[1], "sga")) {
+        if (argc != 3) {
+            sendGenericSyntaxError(cli, "setglobalalert <bytes>");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->setGlobalAlert(atoll(argv[2]));
+        sendGenericOkFail(cli, rc);
+        return 0;
+    }
+    if (!strcmp(argv[1], "debugsettetherglobalalert") || !strcmp(argv[1], "dstga")) {
+        if (argc != 4) {
+            sendGenericSyntaxError(cli, "debugsettetherglobalalert <interface0> <interface1>");
+            return 0;
+        }
+        /* We ignore the interfaces for now. */
+        int rc = sBandwidthCtrl->setGlobalAlertInForwardChain();
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "removeglobalalert") || !strcmp(argv[1], "rga")) {
+        if (argc != 2) {
+            sendGenericSyntaxError(cli, "removeglobalalert");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->removeGlobalAlert();
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "debugremovetetherglobalalert") || !strcmp(argv[1], "drtga")) {
+        if (argc != 4) {
+            sendGenericSyntaxError(cli, "debugremovetetherglobalalert <interface0> <interface1>");
+            return 0;
+        }
+        /* We ignore the interfaces for now. */
+        int rc = sBandwidthCtrl->removeGlobalAlertInForwardChain();
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "setsharedalert") || !strcmp(argv[1], "ssa")) {
+        if (argc != 3) {
+            sendGenericSyntaxError(cli, "setsharedalert <bytes>");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->setSharedAlert(atoll(argv[2]));
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "removesharedalert") || !strcmp(argv[1], "rsa")) {
+        if (argc != 2) {
+            sendGenericSyntaxError(cli, "removesharedalert");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->removeSharedAlert();
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "setinterfacealert") || !strcmp(argv[1], "sia")) {
+        if (argc != 4) {
+            sendGenericSyntaxError(cli, "setinterfacealert <interface> <bytes>");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->setInterfaceAlert(argv[2], atoll(argv[3]));
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "removeinterfacealert") || !strcmp(argv[1], "ria")) {
+        if (argc != 3) {
+            sendGenericSyntaxError(cli, "removeinterfacealert <interface>");
+            return 0;
+        }
+        int rc = sBandwidthCtrl->removeInterfaceAlert(argv[2]);
+        sendGenericOkFail(cli, rc);
+        return 0;
+
+    }
+    if (!strcmp(argv[1], "gettetherstats") || !strcmp(argv[1], "gts")) {
+        BandwidthController::TetherStats tetherStats;
+        std::string extraProcessingInfo = "";
+        if (argc < 2 || argc > 4) {
+            sendGenericSyntaxError(cli, "gettetherstats [<intInterface> <extInterface>]");
+            return 0;
+        }
+        tetherStats.intIface = argc > 2 ? argv[2] : "";
+        tetherStats.extIface = argc > 3 ? argv[3] : "";
+        // No filtering requested and there are no interface pairs to lookup.
+        if (argc <= 2 && sNatCtrl->ifacePairList.empty()) {
+            cli->sendMsg(ResponseCode::CommandOkay, "Tethering stats list completed", false);
+            return 0;
+        }
+        int rc = sBandwidthCtrl->getTetherStats(cli, tetherStats, extraProcessingInfo);
+        if (rc) {
+                extraProcessingInfo.insert(0, "Failed to get tethering stats.\n");
+                sendGenericOpFailed(cli, extraProcessingInfo.c_str());
+                return 0;
+        }
+        return 0;
+
+    }
+
+    cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown bandwidth cmd", false);
+    return 0;
+}
+
+CommandListener::IdletimerControlCmd::IdletimerControlCmd() :
+    NetdCommand("idletimer") {
+}
+
+int CommandListener::IdletimerControlCmd::runCommand(SocketClient *cli, int argc, char **argv) {
+  // TODO(ashish): Change the error statements
+    if (argc < 2) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+        return 0;
+    }
+
+    ALOGV("idletimerctrlcmd: argc=%d %s %s ...", argc, argv[0], argv[1]);
+
+    if (!strcmp(argv[1], "enable")) {
+      if (0 != sIdletimerCtrl->enableIdletimerControl()) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+      } else {
+        cli->sendMsg(ResponseCode::CommandOkay, "Enable success", false);
+      }
+      return 0;
+
+    }
+    if (!strcmp(argv[1], "disable")) {
+      if (0 != sIdletimerCtrl->disableIdletimerControl()) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+      } else {
+        cli->sendMsg(ResponseCode::CommandOkay, "Disable success", false);
+      }
+      return 0;
+    }
+    if (!strcmp(argv[1], "add")) {
+        if (argc != 5) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+            return 0;
+        }
+        if(0 != sIdletimerCtrl->addInterfaceIdletimer(
+                                        argv[2], atoi(argv[3]), argv[4])) {
+          cli->sendMsg(ResponseCode::OperationFailed, "Failed to add interface", false);
+        } else {
+          cli->sendMsg(ResponseCode::CommandOkay,  "Add success", false);
+        }
+        return 0;
+    }
+    if (!strcmp(argv[1], "remove")) {
+        if (argc != 5) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+            return 0;
+        }
+        // ashish: fixme timeout
+        if (0 != sIdletimerCtrl->removeInterfaceIdletimer(
+                                        argv[2], atoi(argv[3]), argv[4])) {
+          cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove interface", false);
+        } else {
+          cli->sendMsg(ResponseCode::CommandOkay, "Remove success", false);
+        }
+        return 0;
+    }
+
+    cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown idletimer cmd", false);
+    return 0;
+}
+
+CommandListener::FirewallCmd::FirewallCmd() :
+    NetdCommand("firewall") {
+}
+
+int CommandListener::FirewallCmd::sendGenericOkFail(SocketClient *cli, int cond) {
+    if (!cond) {
+        cli->sendMsg(ResponseCode::CommandOkay, "Firewall command succeeded", false);
+    } else {
+        cli->sendMsg(ResponseCode::OperationFailed, "Firewall command failed", false);
+    }
+    return 0;
+}
+
+FirewallRule CommandListener::FirewallCmd::parseRule(const char* arg) {
+    if (!strcmp(arg, "allow")) {
+        return ALLOW;
+    } else if (!strcmp(arg, "deny")) {
+        return DENY;
+    } else {
+        ALOGE("failed to parse uid rule (%s)", arg);
+        return ALLOW;
+    }
+}
+
+FirewallType CommandListener::FirewallCmd::parseFirewallType(const char* arg) {
+    if (!strcmp(arg, "whitelist")) {
+        return WHITELIST;
+    } else if (!strcmp(arg, "blacklist")) {
+        return BLACKLIST;
+    } else {
+        ALOGE("failed to parse firewall type (%s)", arg);
+        return BLACKLIST;
+    }
+}
+
+ChildChain CommandListener::FirewallCmd::parseChildChain(const char* arg) {
+    if (!strcmp(arg, "dozable")) {
+        return DOZABLE;
+    } else if (!strcmp(arg, "standby")) {
+        return STANDBY;
+    } else if (!strcmp(arg, "none")) {
+        return NONE;
+    } else {
+        ALOGE("failed to parse child firewall chain (%s)", arg);
+        return INVALID_CHAIN;
+    }
+}
+
+int CommandListener::FirewallCmd::runCommand(SocketClient *cli, int argc,
+        char **argv) {
+    if (argc < 2) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing command", false);
+        return 0;
+    }
+
+    if (!strcmp(argv[1], "enable")) {
+        if (argc != 3) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                        "Usage: firewall enable <whitelist|blacklist>", false);
+            return 0;
+        }
+        FirewallType firewallType = parseFirewallType(argv[2]);
+
+        int res = sFirewallCtrl->enableFirewall(firewallType);
+        return sendGenericOkFail(cli, res);
+    }
+    if (!strcmp(argv[1], "disable")) {
+        int res = sFirewallCtrl->disableFirewall();
+        return sendGenericOkFail(cli, res);
+    }
+    if (!strcmp(argv[1], "is_enabled")) {
+        int res = sFirewallCtrl->isFirewallEnabled();
+        return sendGenericOkFail(cli, res);
+    }
+
+    if (!strcmp(argv[1], "set_interface_rule")) {
+        if (argc != 4) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                         "Usage: firewall set_interface_rule <rmnet0> <allow|deny>", false);
+            return 0;
+        }
+
+        const char* iface = argv[2];
+        FirewallRule rule = parseRule(argv[3]);
+
+        int res = sFirewallCtrl->setInterfaceRule(iface, rule);
+        return sendGenericOkFail(cli, res);
+    }
+
+    if (!strcmp(argv[1], "set_egress_source_rule")) {
+        if (argc != 4) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                         "Usage: firewall set_egress_source_rule <192.168.0.1> <allow|deny>",
+                         false);
+            return 0;
+        }
+
+        const char* addr = argv[2];
+        FirewallRule rule = parseRule(argv[3]);
+
+        int res = sFirewallCtrl->setEgressSourceRule(addr, rule);
+        return sendGenericOkFail(cli, res);
+    }
+
+    if (!strcmp(argv[1], "set_egress_dest_rule")) {
+        if (argc != 5) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                         "Usage: firewall set_egress_dest_rule <192.168.0.1> <80> <allow|deny>",
+                         false);
+            return 0;
+        }
+
+        const char* addr = argv[2];
+        int port = atoi(argv[3]);
+        FirewallRule rule = parseRule(argv[4]);
+
+        int res = 0;
+        res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_TCP, port, rule);
+        res |= sFirewallCtrl->setEgressDestRule(addr, PROTOCOL_UDP, port, rule);
+        return sendGenericOkFail(cli, res);
+    }
+
+    if (!strcmp(argv[1], "set_uid_rule")) {
+        if (argc != 5) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                         "Usage: firewall set_uid_rule <dozable|standby|none> <1000> <allow|deny>",
+                         false);
+            return 0;
+        }
+
+        ChildChain childChain = parseChildChain(argv[2]);
+        if (childChain == INVALID_CHAIN) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                         "Invalid chain name. Valid names are: <dozable|standby|none>",
+                         false);
+            return 0;
+        }
+        int uid = atoi(argv[3]);
+        FirewallRule rule = parseRule(argv[4]);
+        int res = sFirewallCtrl->setUidRule(childChain, uid, rule);
+        return sendGenericOkFail(cli, res);
+    }
+
+    if (!strcmp(argv[1], "enable_chain")) {
+        if (argc != 3) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                         "Usage: firewall enable_chain <dozable|standby>",
+                         false);
+            return 0;
+        }
+
+        ChildChain childChain = parseChildChain(argv[2]);
+        int res = sFirewallCtrl->enableChildChains(childChain, true);
+        return sendGenericOkFail(cli, res);
+    }
+
+    if (!strcmp(argv[1], "disable_chain")) {
+        if (argc != 3) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                         "Usage: firewall disable_chain <dozable|standby>",
+                         false);
+            return 0;
+        }
+
+        ChildChain childChain = parseChildChain(argv[2]);
+        int res = sFirewallCtrl->enableChildChains(childChain, false);
+        return sendGenericOkFail(cli, res);
+    }
+
+    cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false);
+    return 0;
+}
+
+CommandListener::ClatdCmd::ClatdCmd() : NetdCommand("clatd") {
+}
+
+int CommandListener::ClatdCmd::runCommand(SocketClient *cli, int argc,
+                                                            char **argv) {
+    int rc = 0;
+    if (argc < 3) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+        return 0;
+    }
+
+    if (!strcmp(argv[1], "stop")) {
+        rc = sClatdCtrl->stopClatd(argv[2]);
+    } else if (!strcmp(argv[1], "status")) {
+        char *tmp = NULL;
+        asprintf(&tmp, "Clatd status: %s", (sClatdCtrl->isClatdStarted(argv[2]) ?
+                                            "started" : "stopped"));
+        cli->sendMsg(ResponseCode::ClatdStatusResult, tmp, false);
+        free(tmp);
+        return 0;
+    } else if (!strcmp(argv[1], "start")) {
+        rc = sClatdCtrl->startClatd(argv[2]);
+    } else {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown clatd cmd", false);
+        return 0;
+    }
+
+    if (!rc) {
+        cli->sendMsg(ResponseCode::CommandOkay, "Clatd operation succeeded", false);
+    } else {
+        cli->sendMsg(ResponseCode::OperationFailed, "Clatd operation failed", false);
+    }
+
+    return 0;
+}
+
+CommandListener::StrictCmd::StrictCmd() :
+    NetdCommand("strict") {
+}
+
+int CommandListener::StrictCmd::sendGenericOkFail(SocketClient *cli, int cond) {
+    if (!cond) {
+        cli->sendMsg(ResponseCode::CommandOkay, "Strict command succeeded", false);
+    } else {
+        cli->sendMsg(ResponseCode::OperationFailed, "Strict command failed", false);
+    }
+    return 0;
+}
+
+StrictPenalty CommandListener::StrictCmd::parsePenalty(const char* arg) {
+    if (!strcmp(arg, "reject")) {
+        return REJECT;
+    } else if (!strcmp(arg, "log")) {
+        return LOG;
+    } else if (!strcmp(arg, "accept")) {
+        return ACCEPT;
+    } else {
+        return INVALID;
+    }
+}
+
+int CommandListener::StrictCmd::runCommand(SocketClient *cli, int argc,
+        char **argv) {
+    if (argc < 2) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing command", false);
+        return 0;
+    }
+
+    if (!strcmp(argv[1], "enable")) {
+        int res = sStrictCtrl->enableStrict();
+        return sendGenericOkFail(cli, res);
+    }
+    if (!strcmp(argv[1], "disable")) {
+        int res = sStrictCtrl->disableStrict();
+        return sendGenericOkFail(cli, res);
+    }
+
+    if (!strcmp(argv[1], "set_uid_cleartext_policy")) {
+        if (argc != 4) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError,
+                         "Usage: strict set_uid_cleartext_policy <uid> <accept|log|reject>",
+                         false);
+            return 0;
+        }
+
+        errno = 0;
+        unsigned long int uid = strtoul(argv[2], NULL, 0);
+        if (errno || uid > UID_MAX) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError, "Invalid UID", false);
+            return 0;
+        }
+
+        StrictPenalty penalty = parsePenalty(argv[3]);
+        if (penalty == INVALID) {
+            cli->sendMsg(ResponseCode::CommandSyntaxError, "Invalid penalty argument", false);
+            return 0;
+        }
+
+        int res = sStrictCtrl->setUidCleartextPenalty((uid_t) uid, penalty);
+        return sendGenericOkFail(cli, res);
+    }
+
+    cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false);
+    return 0;
+}
+
+CommandListener::NetworkCommand::NetworkCommand() : NetdCommand("network") {
+}
+
+int CommandListener::NetworkCommand::syntaxError(SocketClient* client, const char* message) {
+    client->sendMsg(ResponseCode::CommandSyntaxError, message, false);
+    return 0;
+}
+
+int CommandListener::NetworkCommand::operationError(SocketClient* client, const char* message,
+                                                    int ret) {
+    errno = -ret;
+    client->sendMsg(ResponseCode::OperationFailed, message, true);
+    return 0;
+}
+
+int CommandListener::NetworkCommand::success(SocketClient* client) {
+    client->sendMsg(ResponseCode::CommandOkay, "success", false);
+    return 0;
+}
+
+int CommandListener::NetworkCommand::runCommand(SocketClient* client, int argc, char** argv) {
+    if (argc < 2) {
+        return syntaxError(client, "Missing argument");
+    }
+
+    //    0      1      2      3      4       5         6            7           8
+    // network route [legacy <uid>]  add   <netId> <interface> <destination> [nexthop]
+    // network route [legacy <uid>] remove <netId> <interface> <destination> [nexthop]
+    //
+    // nexthop may be either an IPv4/IPv6 address or one of "unreachable" or "throw".
+    if (!strcmp(argv[1], "route")) {
+        if (argc < 6 || argc > 9) {
+            return syntaxError(client, "Incorrect number of arguments");
+        }
+
+        int nextArg = 2;
+        bool legacy = false;
+        uid_t uid = 0;
+        if (!strcmp(argv[nextArg], "legacy")) {
+            ++nextArg;
+            legacy = true;
+            uid = strtoul(argv[nextArg++], NULL, 0);
+        }
+
+        bool add = false;
+        if (!strcmp(argv[nextArg], "add")) {
+            add = true;
+        } else if (strcmp(argv[nextArg], "remove")) {
+            return syntaxError(client, "Unknown argument");
+        }
+        ++nextArg;
+
+        if (argc < nextArg + 3 || argc > nextArg + 4) {
+            return syntaxError(client, "Incorrect number of arguments");
+        }
+
+        unsigned netId = stringToNetId(argv[nextArg++]);
+        const char* interface = argv[nextArg++];
+        const char* destination = argv[nextArg++];
+        const char* nexthop = argc > nextArg ? argv[nextArg] : NULL;
+
+        int ret;
+        if (add) {
+            ret = sNetCtrl->addRoute(netId, interface, destination, nexthop, legacy, uid);
+        } else {
+            ret = sNetCtrl->removeRoute(netId, interface, destination, nexthop, legacy, uid);
+        }
+        if (ret) {
+            return operationError(client, add ? "addRoute() failed" : "removeRoute() failed", ret);
+        }
+
+        return success(client);
+    }
+
+    //    0        1       2       3         4
+    // network interface  add   <netId> <interface>
+    // network interface remove <netId> <interface>
+    if (!strcmp(argv[1], "interface")) {
+        if (argc != 5) {
+            return syntaxError(client, "Missing argument");
+        }
+        unsigned netId = stringToNetId(argv[3]);
+        if (!strcmp(argv[2], "add")) {
+            if (int ret = sNetCtrl->addInterfaceToNetwork(netId, argv[4])) {
+                return operationError(client, "addInterfaceToNetwork() failed", ret);
+            }
+        } else if (!strcmp(argv[2], "remove")) {
+            if (int ret = sNetCtrl->removeInterfaceFromNetwork(netId, argv[4])) {
+                return operationError(client, "removeInterfaceFromNetwork() failed", ret);
+            }
+        } else {
+            return syntaxError(client, "Unknown argument");
+        }
+        return success(client);
+    }
+
+    //    0      1       2         3
+    // network create <netId> [permission]
+    //
+    //    0      1       2     3     4        5
+    // network create <netId> vpn <hasDns> <secure>
+    if (!strcmp(argv[1], "create")) {
+        if (argc < 3) {
+            return syntaxError(client, "Missing argument");
+        }
+        unsigned netId = stringToNetId(argv[2]);
+        if (argc == 6 && !strcmp(argv[3], "vpn")) {
+            bool hasDns = atoi(argv[4]);
+            bool secure = atoi(argv[5]);
+            if (int ret = sNetCtrl->createVirtualNetwork(netId, hasDns, secure)) {
+                return operationError(client, "createVirtualNetwork() failed", ret);
+            }
+        } else if (argc > 4) {
+            return syntaxError(client, "Unknown trailing argument(s)");
+        } else {
+            Permission permission = PERMISSION_NONE;
+            if (argc == 4) {
+                permission = stringToPermission(argv[3]);
+                if (permission == PERMISSION_NONE) {
+                    return syntaxError(client, "Unknown permission");
+                }
+            }
+            if (int ret = sNetCtrl->createPhysicalNetwork(netId, permission)) {
+                return operationError(client, "createPhysicalNetwork() failed", ret);
+            }
+        }
+        return success(client);
+    }
+
+    //    0       1       2
+    // network destroy <netId>
+    if (!strcmp(argv[1], "destroy")) {
+        if (argc != 3) {
+            return syntaxError(client, "Incorrect number of arguments");
+        }
+        unsigned netId = stringToNetId(argv[2]);
+        if (int ret = sNetCtrl->destroyNetwork(netId)) {
+            return operationError(client, "destroyNetwork() failed", ret);
+        }
+        return success(client);
+    }
+
+    //    0       1      2      3
+    // network default  set  <netId>
+    // network default clear
+    if (!strcmp(argv[1], "default")) {
+        if (argc < 3) {
+            return syntaxError(client, "Missing argument");
+        }
+        unsigned netId = NETID_UNSET;
+        if (!strcmp(argv[2], "set")) {
+            if (argc < 4) {
+                return syntaxError(client, "Missing netId");
+            }
+            netId = stringToNetId(argv[3]);
+        } else if (strcmp(argv[2], "clear")) {
+            return syntaxError(client, "Unknown argument");
+        }
+        if (int ret = sNetCtrl->setDefaultNetwork(netId)) {
+            return operationError(client, "setDefaultNetwork() failed", ret);
+        }
+        return success(client);
+    }
+
+    //    0        1         2      3        4          5
+    // network permission   user   set  <permission>  <uid> ...
+    // network permission   user  clear    <uid> ...
+    // network permission network  set  <permission> <netId> ...
+    // network permission network clear   <netId> ...
+    if (!strcmp(argv[1], "permission")) {
+        if (argc < 5) {
+            return syntaxError(client, "Missing argument");
+        }
+        int nextArg = 4;
+        Permission permission = PERMISSION_NONE;
+        if (!strcmp(argv[3], "set")) {
+            permission = stringToPermission(argv[4]);
+            if (permission == PERMISSION_NONE) {
+                return syntaxError(client, "Unknown permission");
+            }
+            nextArg = 5;
+        } else if (strcmp(argv[3], "clear")) {
+            return syntaxError(client, "Unknown argument");
+        }
+        if (nextArg == argc) {
+            return syntaxError(client, "Missing id");
+        }
+
+        bool userPermissions = !strcmp(argv[2], "user");
+        bool networkPermissions = !strcmp(argv[2], "network");
+        if (!userPermissions && !networkPermissions) {
+            return syntaxError(client, "Unknown argument");
+        }
+
+        std::vector<unsigned> ids;
+        for (; nextArg < argc; ++nextArg) {
+            if (userPermissions) {
+                char* endPtr;
+                unsigned id = strtoul(argv[nextArg], &endPtr, 0);
+                if (!*argv[nextArg] || *endPtr) {
+                    return syntaxError(client, "Invalid id");
+                }
+                ids.push_back(id);
+            } else {
+                // networkPermissions
+                ids.push_back(stringToNetId(argv[nextArg]));
+            }
+        }
+        if (userPermissions) {
+            sNetCtrl->setPermissionForUsers(permission, ids);
+        } else {
+            // networkPermissions
+            if (int ret = sNetCtrl->setPermissionForNetworks(permission, ids)) {
+                return operationError(client, "setPermissionForNetworks() failed", ret);
+            }
+        }
+
+        return success(client);
+    }
+
+    //    0      1     2       3           4
+    // network users  add   <netId> [<uid>[-<uid>]] ...
+    // network users remove <netId> [<uid>[-<uid>]] ...
+    if (!strcmp(argv[1], "users")) {
+        if (argc < 4) {
+            return syntaxError(client, "Missing argument");
+        }
+        unsigned netId = stringToNetId(argv[3]);
+        UidRanges uidRanges;
+        if (!uidRanges.parseFrom(argc - 4, argv + 4)) {
+            return syntaxError(client, "Invalid UIDs");
+        }
+        if (!strcmp(argv[2], "add")) {
+            if (int ret = sNetCtrl->addUsersToNetwork(netId, uidRanges)) {
+                return operationError(client, "addUsersToNetwork() failed", ret);
+            }
+        } else if (!strcmp(argv[2], "remove")) {
+            if (int ret = sNetCtrl->removeUsersFromNetwork(netId, uidRanges)) {
+                return operationError(client, "removeUsersFromNetwork() failed", ret);
+            }
+        } else {
+            return syntaxError(client, "Unknown argument");
+        }
+        return success(client);
+    }
+
+    //    0       1      2     3
+    // network protect allow <uid> ...
+    // network protect  deny <uid> ...
+    if (!strcmp(argv[1], "protect")) {
+        if (argc < 4) {
+            return syntaxError(client, "Missing argument");
+        }
+        std::vector<uid_t> uids;
+        for (int i = 3; i < argc; ++i) {
+            uids.push_back(strtoul(argv[i], NULL, 0));
+        }
+        if (!strcmp(argv[2], "allow")) {
+            sNetCtrl->allowProtect(uids);
+        } else if (!strcmp(argv[2], "deny")) {
+            sNetCtrl->denyProtect(uids);
+        } else {
+            return syntaxError(client, "Unknown argument");
+        }
+        return success(client);
+    }
+
+    return syntaxError(client, "Unknown argument");
+}
diff --git a/netd/server/CommandListener.h b/netd/server/CommandListener.h
new file mode 100644
index 0000000..6846323
--- /dev/null
+++ b/netd/server/CommandListener.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _COMMANDLISTENER_H__
+#define _COMMANDLISTENER_H__
+
+#include <sysutils/FrameworkListener.h>
+
+#include "NetdCommand.h"
+#include "NetworkController.h"
+#include "TetherController.h"
+#include "NatController.h"
+#include "PppController.h"
+#include "SoftapController.h"
+#include "BandwidthController.h"
+#include "IdletimerController.h"
+#include "InterfaceController.h"
+#include "ResolverController.h"
+#include "FirewallController.h"
+#include "ClatdController.h"
+#include "StrictController.h"
+
+class CommandListener : public FrameworkListener {
+    static TetherController *sTetherCtrl;
+    static NatController *sNatCtrl;
+    static PppController *sPppCtrl;
+    static SoftapController *sSoftapCtrl;
+    static BandwidthController *sBandwidthCtrl;
+    static IdletimerController *sIdletimerCtrl;
+    static InterfaceController *sInterfaceCtrl;
+    static ResolverController *sResolverCtrl;
+    static FirewallController *sFirewallCtrl;
+    static ClatdController *sClatdCtrl;
+    static StrictController *sStrictCtrl;
+
+public:
+    static NetworkController *sNetCtrl;
+
+    CommandListener();
+    virtual ~CommandListener() {}
+
+private:
+
+    class SoftapCmd : public NetdCommand {
+    public:
+        SoftapCmd();
+        virtual ~SoftapCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
+    class InterfaceCmd : public NetdCommand {
+    public:
+        InterfaceCmd();
+        virtual ~InterfaceCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
+    class IpFwdCmd : public NetdCommand {
+    public:
+        IpFwdCmd();
+        virtual ~IpFwdCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
+    class TetherCmd : public NetdCommand {
+    public:
+        TetherCmd();
+        virtual ~TetherCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
+    class NatCmd : public NetdCommand {
+    public:
+        NatCmd();
+        virtual ~NatCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
+    class ListTtysCmd : public NetdCommand {
+    public:
+        ListTtysCmd();
+        virtual ~ListTtysCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
+    class PppdCmd : public NetdCommand {
+    public:
+        PppdCmd();
+        virtual ~PppdCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
+    class BandwidthControlCmd : public NetdCommand {
+    public:
+        BandwidthControlCmd();
+        virtual ~BandwidthControlCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    protected:
+        void sendGenericOkFail(SocketClient *cli, int cond);
+        void sendGenericOpFailed(SocketClient *cli, const char *errMsg);
+        void sendGenericSyntaxError(SocketClient *cli, const char *usageMsg);
+    };
+
+    class IdletimerControlCmd : public NetdCommand {
+    public:
+        IdletimerControlCmd();
+        virtual ~IdletimerControlCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
+    class ResolverCmd : public NetdCommand {
+    public:
+        ResolverCmd();
+        virtual ~ResolverCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+
+    private:
+        bool parseAndExecuteSetNetDns(int netId, int argc, const char** argv);
+    };
+
+    class FirewallCmd: public NetdCommand {
+    public:
+        FirewallCmd();
+        virtual ~FirewallCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    protected:
+        int sendGenericOkFail(SocketClient *cli, int cond);
+        static FirewallRule parseRule(const char* arg);
+        static FirewallType parseFirewallType(const char* arg);
+        static ChildChain parseChildChain(const char* arg);
+    };
+
+    class ClatdCmd : public NetdCommand {
+    public:
+        ClatdCmd();
+        virtual ~ClatdCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
+    class StrictCmd : public NetdCommand {
+    public:
+        StrictCmd();
+        virtual ~StrictCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    protected:
+        int sendGenericOkFail(SocketClient *cli, int cond);
+        static StrictPenalty parsePenalty(const char* arg);
+    };
+
+    class NetworkCommand : public NetdCommand {
+    public:
+        NetworkCommand();
+        virtual ~NetworkCommand() {}
+        int runCommand(SocketClient* client, int argc, char** argv);
+    private:
+        int syntaxError(SocketClient* cli, const char* message);
+        int operationError(SocketClient* cli, const char* message, int ret);
+        int success(SocketClient* cli);
+    };
+};
+
+#endif
diff --git a/netd/server/ConnmarkFlags.h b/netd/server/ConnmarkFlags.h
new file mode 100644
index 0000000..2bbefc0
--- /dev/null
+++ b/netd/server/ConnmarkFlags.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#ifndef _CONNMARK_FLAGS_H
+#define _CONNMARK_FLAGS_H
+
+/*
+ * iptables CONNMARK flag values used by various controllers. These values
+ * need to be stored in one place to avoid clashes.
+ */
+class ConnmarkFlags {
+public:
+    static const unsigned int STRICT_RESOLVED_ACCEPT = 0x01000000;
+    static const unsigned int STRICT_RESOLVED_REJECT = 0x02000000;
+};
+
+#endif
diff --git a/netd/server/DnsProxyListener.cpp b/netd/server/DnsProxyListener.cpp
new file mode 100644
index 0000000..6c71c5b
--- /dev/null
+++ b/netd/server/DnsProxyListener.cpp
@@ -0,0 +1,488 @@
+/*
+ * 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.
+ */
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <errno.h>
+#include <linux/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <string.h>
+#include <pthread.h>
+#include <resolv_netid.h>
+#include <net/if.h>
+
+#define LOG_TAG "DnsProxyListener"
+#define DBG 0
+#define VDBG 0
+
+#include <cutils/log.h>
+#include <sysutils/SocketClient.h>
+
+#include "Fwmark.h"
+#include "DnsProxyListener.h"
+#include "NetdConstants.h"
+#include "NetworkController.h"
+#include "ResponseCode.h"
+
+DnsProxyListener::DnsProxyListener(const NetworkController* netCtrl) :
+        FrameworkListener("dnsproxyd"), mNetCtrl(netCtrl) {
+    registerCmd(new GetAddrInfoCmd(this));
+    registerCmd(new GetHostByAddrCmd(this));
+    registerCmd(new GetHostByNameCmd(this));
+}
+
+DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(
+        SocketClient *c, char* host, char* service, struct addrinfo* hints,
+        const struct android_net_context& netcontext)
+        : mClient(c),
+          mHost(host),
+          mService(service),
+          mHints(hints),
+          mNetContext(netcontext) {
+}
+
+DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() {
+    free(mHost);
+    free(mService);
+    free(mHints);
+}
+
+void DnsProxyListener::GetAddrInfoHandler::start() {
+    pthread_t thread;
+    pthread_create(&thread, NULL,
+                   DnsProxyListener::GetAddrInfoHandler::threadStart, this);
+    pthread_detach(thread);
+}
+
+void* DnsProxyListener::GetAddrInfoHandler::threadStart(void* obj) {
+    GetAddrInfoHandler* handler = reinterpret_cast<GetAddrInfoHandler*>(obj);
+    handler->run();
+    delete handler;
+    pthread_exit(NULL);
+    return NULL;
+}
+
+static bool sendBE32(SocketClient* c, uint32_t data) {
+    uint32_t be_data = htonl(data);
+    return c->sendData(&be_data, sizeof(be_data)) == 0;
+}
+
+// Sends 4 bytes of big-endian length, followed by the data.
+// Returns true on success.
+static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
+    return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
+}
+
+// Returns true on success
+static bool sendhostent(SocketClient *c, struct hostent *hp) {
+    bool success = true;
+    int i;
+    if (hp->h_name != NULL) {
+        success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name);
+    } else {
+        success &= sendLenAndData(c, 0, "") == 0;
+    }
+
+    for (i=0; hp->h_aliases[i] != NULL; i++) {
+        success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]);
+    }
+    success &= sendLenAndData(c, 0, ""); // null to indicate we're done
+
+    uint32_t buf = htonl(hp->h_addrtype);
+    success &= c->sendData(&buf, sizeof(buf)) == 0;
+
+    buf = htonl(hp->h_length);
+    success &= c->sendData(&buf, sizeof(buf)) == 0;
+
+    for (i=0; hp->h_addr_list[i] != NULL; i++) {
+        success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
+    }
+    success &= sendLenAndData(c, 0, ""); // null to indicate we're done
+    return success;
+}
+
+static bool sendaddrinfo(SocketClient* c, struct addrinfo* ai) {
+    // struct addrinfo {
+    //      int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
+    //      int     ai_family;      /* PF_xxx */
+    //      int     ai_socktype;    /* SOCK_xxx */
+    //      int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+    //      socklen_t ai_addrlen;   /* length of ai_addr */
+    //      char    *ai_canonname;  /* canonical name for hostname */
+    //      struct  sockaddr *ai_addr;      /* binary address */
+    //      struct  addrinfo *ai_next;      /* next structure in linked list */
+    // };
+
+    // Write the struct piece by piece because we might be a 64-bit netd
+    // talking to a 32-bit process.
+    bool success =
+            sendBE32(c, ai->ai_flags) &&
+            sendBE32(c, ai->ai_family) &&
+            sendBE32(c, ai->ai_socktype) &&
+            sendBE32(c, ai->ai_protocol);
+    if (!success) {
+        return false;
+    }
+
+    // ai_addrlen and ai_addr.
+    if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
+        return false;
+    }
+
+    // strlen(ai_canonname) and ai_canonname.
+    if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
+        return false;
+    }
+
+    return true;
+}
+
+void DnsProxyListener::GetAddrInfoHandler::run() {
+    if (DBG) {
+        ALOGD("GetAddrInfoHandler, now for %s / %s / {%u,%u,%u,%u,%u}", mHost, mService,
+                mNetContext.app_netid, mNetContext.app_mark,
+                mNetContext.dns_netid, mNetContext.dns_mark,
+                mNetContext.uid);
+    }
+
+    struct addrinfo* result = NULL;
+    uint32_t rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, &result);
+    if (rv) {
+        // getaddrinfo failed
+        mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
+    } else {
+        bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
+        struct addrinfo* ai = result;
+        while (ai && success) {
+            success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
+            ai = ai->ai_next;
+        }
+        success = success && sendBE32(mClient, 0);
+        if (!success) {
+            ALOGW("Error writing DNS result to client");
+        }
+    }
+    if (result) {
+        freeaddrinfo(result);
+    }
+    mClient->decRef();
+}
+
+DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd(const DnsProxyListener* dnsProxyListener) :
+    NetdCommand("getaddrinfo"),
+    mDnsProxyListener(dnsProxyListener) {
+}
+
+int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    if (DBG) {
+        for (int i = 0; i < argc; i++) {
+            ALOGD("argv[%i]=%s", i, argv[i]);
+        }
+    }
+    if (argc != 8) {
+        char* msg = NULL;
+        asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc);
+        ALOGW("%s", msg);
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    char* name = argv[1];
+    if (strcmp("^", name) == 0) {
+        name = NULL;
+    } else {
+        name = strdup(name);
+    }
+
+    char* service = argv[2];
+    if (strcmp("^", service) == 0) {
+        service = NULL;
+    } else {
+        service = strdup(service);
+    }
+
+    struct addrinfo* hints = NULL;
+    int ai_flags = atoi(argv[3]);
+    int ai_family = atoi(argv[4]);
+    int ai_socktype = atoi(argv[5]);
+    int ai_protocol = atoi(argv[6]);
+    unsigned netId = strtoul(argv[7], NULL, 10);
+    uid_t uid = cli->getUid();
+
+    struct android_net_context netcontext;
+    mDnsProxyListener->mNetCtrl->getNetworkContext(netId, uid, &netcontext);
+
+    if (ai_flags != -1 || ai_family != -1 ||
+        ai_socktype != -1 || ai_protocol != -1) {
+        hints = (struct addrinfo*) calloc(1, sizeof(struct addrinfo));
+        hints->ai_flags = ai_flags;
+        hints->ai_family = ai_family;
+        hints->ai_socktype = ai_socktype;
+        hints->ai_protocol = ai_protocol;
+
+        // Only implement AI_ADDRCONFIG if application is using default network since our
+        // implementation only works on the default network.
+        if ((hints->ai_flags & AI_ADDRCONFIG) &&
+                netcontext.dns_netid != mDnsProxyListener->mNetCtrl->getDefaultNetwork()) {
+            hints->ai_flags &= ~AI_ADDRCONFIG;
+        }
+    }
+
+    if (DBG) {
+        ALOGD("GetAddrInfoHandler for %s / %s / {%u,%u,%u,%u,%u}",
+             name ? name : "[nullhost]",
+             service ? service : "[nullservice]",
+             netcontext.app_netid, netcontext.app_mark,
+             netcontext.dns_netid, netcontext.dns_mark,
+             netcontext.uid);
+    }
+
+    cli->incRef();
+    DnsProxyListener::GetAddrInfoHandler* handler =
+            new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext);
+    handler->start();
+
+    return 0;
+}
+
+/*******************************************************
+ *                  GetHostByName                      *
+ *******************************************************/
+DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd(const DnsProxyListener* dnsProxyListener) :
+      NetdCommand("gethostbyname"),
+      mDnsProxyListener(dnsProxyListener) {
+}
+
+int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    if (DBG) {
+        for (int i = 0; i < argc; i++) {
+            ALOGD("argv[%i]=%s", i, argv[i]);
+        }
+    }
+    if (argc != 4) {
+        char* msg = NULL;
+        asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
+        ALOGW("%s", msg);
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    uid_t uid = cli->getUid();
+    unsigned netId = strtoul(argv[1], NULL, 10);
+    char* name = argv[2];
+    int af = atoi(argv[3]);
+
+    if (strcmp(name, "^") == 0) {
+        name = NULL;
+    } else {
+        name = strdup(name);
+    }
+
+    uint32_t mark = mDnsProxyListener->mNetCtrl->getNetworkForDns(&netId, uid);
+
+    cli->incRef();
+    DnsProxyListener::GetHostByNameHandler* handler =
+            new DnsProxyListener::GetHostByNameHandler(cli, name, af, netId, mark);
+    handler->start();
+
+    return 0;
+}
+
+DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c,
+                                                             char* name,
+                                                             int af,
+                                                             unsigned netId,
+                                                             uint32_t mark)
+        : mClient(c),
+          mName(name),
+          mAf(af),
+          mNetId(netId),
+          mMark(mark) {
+}
+
+DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
+    free(mName);
+}
+
+void DnsProxyListener::GetHostByNameHandler::start() {
+    pthread_t thread;
+    pthread_create(&thread, NULL,
+            DnsProxyListener::GetHostByNameHandler::threadStart, this);
+    pthread_detach(thread);
+}
+
+void* DnsProxyListener::GetHostByNameHandler::threadStart(void* obj) {
+    GetHostByNameHandler* handler = reinterpret_cast<GetHostByNameHandler*>(obj);
+    handler->run();
+    delete handler;
+    pthread_exit(NULL);
+    return NULL;
+}
+
+void DnsProxyListener::GetHostByNameHandler::run() {
+    if (DBG) {
+        ALOGD("DnsProxyListener::GetHostByNameHandler::run\n");
+    }
+
+    struct hostent* hp;
+
+    hp = android_gethostbynamefornet(mName, mAf, mNetId, mMark);
+
+    if (DBG) {
+        ALOGD("GetHostByNameHandler::run gethostbyname errno: %s hp->h_name = %s, name_len = %zu\n",
+                hp ? "success" : strerror(errno),
+                (hp && hp->h_name) ? hp->h_name : "null",
+                (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0);
+    }
+
+    bool success = true;
+    if (hp) {
+        success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
+        success &= sendhostent(mClient, hp);
+    } else {
+        success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0;
+    }
+
+    if (!success) {
+        ALOGW("GetHostByNameHandler: Error writing DNS result to client\n");
+    }
+    mClient->decRef();
+}
+
+
+/*******************************************************
+ *                  GetHostByAddr                      *
+ *******************************************************/
+DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd(const DnsProxyListener* dnsProxyListener) :
+        NetdCommand("gethostbyaddr"),
+        mDnsProxyListener(dnsProxyListener) {
+}
+
+int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    if (DBG) {
+        for (int i = 0; i < argc; i++) {
+            ALOGD("argv[%i]=%s", i, argv[i]);
+        }
+    }
+    if (argc != 5) {
+        char* msg = NULL;
+        asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
+        ALOGW("%s", msg);
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    char* addrStr = argv[1];
+    int addrLen = atoi(argv[2]);
+    int addrFamily = atoi(argv[3]);
+    uid_t uid = cli->getUid();
+    unsigned netId = strtoul(argv[4], NULL, 10);
+
+    void* addr = malloc(sizeof(struct in6_addr));
+    errno = 0;
+    int result = inet_pton(addrFamily, addrStr, addr);
+    if (result <= 0) {
+        char* msg = NULL;
+        asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
+        ALOGW("%s", msg);
+        cli->sendMsg(ResponseCode::OperationFailed, msg, false);
+        free(addr);
+        free(msg);
+        return -1;
+    }
+
+    uint32_t mark = mDnsProxyListener->mNetCtrl->getNetworkForDns(&netId, uid);
+
+    cli->incRef();
+    DnsProxyListener::GetHostByAddrHandler* handler =
+            new DnsProxyListener::GetHostByAddrHandler(cli, addr, addrLen, addrFamily, netId, mark);
+    handler->start();
+
+    return 0;
+}
+
+DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c,
+                                                             void* address,
+                                                             int   addressLen,
+                                                             int   addressFamily,
+                                                             unsigned netId,
+                                                             uint32_t mark)
+        : mClient(c),
+          mAddress(address),
+          mAddressLen(addressLen),
+          mAddressFamily(addressFamily),
+          mNetId(netId),
+          mMark(mark) {
+}
+
+DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
+    free(mAddress);
+}
+
+void DnsProxyListener::GetHostByAddrHandler::start() {
+    pthread_t thread;
+    pthread_create(&thread, NULL,
+                   DnsProxyListener::GetHostByAddrHandler::threadStart, this);
+    pthread_detach(thread);
+}
+
+void* DnsProxyListener::GetHostByAddrHandler::threadStart(void* obj) {
+    GetHostByAddrHandler* handler = reinterpret_cast<GetHostByAddrHandler*>(obj);
+    handler->run();
+    delete handler;
+    pthread_exit(NULL);
+    return NULL;
+}
+
+void DnsProxyListener::GetHostByAddrHandler::run() {
+    if (DBG) {
+        ALOGD("DnsProxyListener::GetHostByAddrHandler::run\n");
+    }
+    struct hostent* hp;
+
+    // NOTE gethostbyaddr should take a void* but bionic thinks it should be char*
+    hp = android_gethostbyaddrfornet((char*)mAddress, mAddressLen, mAddressFamily, mNetId, mMark);
+
+    if (DBG) {
+        ALOGD("GetHostByAddrHandler::run gethostbyaddr errno: %s hp->h_name = %s, name_len = %zu\n",
+                hp ? "success" : strerror(errno),
+                (hp && hp->h_name) ? hp->h_name : "null",
+                (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0);
+    }
+
+    bool success = true;
+    if (hp) {
+        success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
+        success &= sendhostent(mClient, hp);
+    } else {
+        success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0;
+    }
+
+    if (!success) {
+        ALOGW("GetHostByAddrHandler: Error writing DNS result to client\n");
+    }
+    mClient->decRef();
+}
diff --git a/netd/server/DnsProxyListener.h b/netd/server/DnsProxyListener.h
new file mode 100644
index 0000000..b67ad5c
--- /dev/null
+++ b/netd/server/DnsProxyListener.h
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+#ifndef _DNSPROXYLISTENER_H__
+#define _DNSPROXYLISTENER_H__
+
+#include <resolv_netid.h>  // struct android_net_context
+#include <sysutils/FrameworkListener.h>
+
+#include "NetdCommand.h"
+
+class NetworkController;
+
+class DnsProxyListener : public FrameworkListener {
+public:
+    explicit DnsProxyListener(const NetworkController* netCtrl);
+    virtual ~DnsProxyListener() {}
+
+private:
+    const NetworkController *mNetCtrl;
+    class GetAddrInfoCmd : public NetdCommand {
+    public:
+        explicit GetAddrInfoCmd(const DnsProxyListener* dnsProxyListener);
+        virtual ~GetAddrInfoCmd() {}
+        int runCommand(SocketClient *c, int argc, char** argv);
+    private:
+        const DnsProxyListener* mDnsProxyListener;
+    };
+
+    class GetAddrInfoHandler {
+    public:
+        // Note: All of host, service, and hints may be NULL
+        GetAddrInfoHandler(SocketClient *c,
+                           char* host,
+                           char* service,
+                           struct addrinfo* hints,
+                           const struct android_net_context& netcontext);
+        ~GetAddrInfoHandler();
+
+        static void* threadStart(void* handler);
+        void start();
+
+    private:
+        void run();
+        SocketClient* mClient;  // ref counted
+        char* mHost;    // owned
+        char* mService; // owned
+        struct addrinfo* mHints;  // owned
+        struct android_net_context mNetContext;
+    };
+
+    /* ------ gethostbyname ------*/
+    class GetHostByNameCmd : public NetdCommand {
+    public:
+        explicit GetHostByNameCmd(const DnsProxyListener* dnsProxyListener);
+        virtual ~GetHostByNameCmd() {}
+        int runCommand(SocketClient *c, int argc, char** argv);
+    private:
+        const DnsProxyListener* mDnsProxyListener;
+    };
+
+    class GetHostByNameHandler {
+    public:
+        GetHostByNameHandler(SocketClient *c,
+                            char *name,
+                            int af,
+                            unsigned netId,
+                            uint32_t mark);
+        ~GetHostByNameHandler();
+        static void* threadStart(void* handler);
+        void start();
+    private:
+        void run();
+        SocketClient* mClient; //ref counted
+        char* mName; // owned
+        int mAf;
+        unsigned mNetId;
+        uint32_t mMark;
+    };
+
+    /* ------ gethostbyaddr ------*/
+    class GetHostByAddrCmd : public NetdCommand {
+    public:
+        explicit GetHostByAddrCmd(const DnsProxyListener* dnsProxyListener);
+        virtual ~GetHostByAddrCmd() {}
+        int runCommand(SocketClient *c, int argc, char** argv);
+    private:
+        const DnsProxyListener* mDnsProxyListener;
+    };
+
+    class GetHostByAddrHandler {
+    public:
+        GetHostByAddrHandler(SocketClient *c,
+                            void* address,
+                            int addressLen,
+                            int addressFamily,
+                            unsigned netId,
+                            uint32_t mark);
+        ~GetHostByAddrHandler();
+
+        static void* threadStart(void* handler);
+        void start();
+
+    private:
+        void run();
+        SocketClient* mClient;  // ref counted
+        void* mAddress;    // address to lookup; owned
+        int mAddressLen; // length of address to look up
+        int mAddressFamily;  // address family
+        unsigned mNetId;
+        uint32_t mMark;
+    };
+};
+
+#endif
diff --git a/netd/server/DummyNetwork.cpp b/netd/server/DummyNetwork.cpp
new file mode 100644
index 0000000..a3b3435
--- /dev/null
+++ b/netd/server/DummyNetwork.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 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 "DummyNetwork.h"
+
+#include "RouteController.h"
+
+#define LOG_TAG "Netd"
+#include "log/log.h"
+#include "errno.h"
+
+const char* DummyNetwork::INTERFACE_NAME = "dummy0";
+
+DummyNetwork::DummyNetwork(unsigned netId) : Network(netId) {
+    mInterfaces.insert(INTERFACE_NAME);
+}
+
+DummyNetwork::~DummyNetwork() {
+}
+
+Network::Type DummyNetwork::getType() const {
+    return DUMMY;
+}
+
+int DummyNetwork::addInterface(const std::string& /* interface */) {
+    return -EINVAL;
+}
+
+int DummyNetwork::removeInterface(const std::string& /* interface */) {
+    return -EINVAL;
+}
diff --git a/netd/server/DummyNetwork.h b/netd/server/DummyNetwork.h
new file mode 100644
index 0000000..7bc0d3d
--- /dev/null
+++ b/netd/server/DummyNetwork.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_SERVER_DUMMY_NETWORK_H
+#define NETD_SERVER_DUMMY_NETWORK_H
+
+#include "Network.h"
+
+class DummyNetwork : public Network {
+public:
+    static const char* INTERFACE_NAME;
+    explicit DummyNetwork(unsigned netId);
+    virtual ~DummyNetwork();
+
+private:
+    Type getType() const override;
+    int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+    int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+};
+
+#endif  // NETD_SERVER_DUMMY_NETWORK_H
diff --git a/netd/server/FirewallController.cpp b/netd/server/FirewallController.cpp
new file mode 100644
index 0000000..cf5a7de
--- /dev/null
+++ b/netd/server/FirewallController.cpp
@@ -0,0 +1,295 @@
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define LOG_TAG "FirewallController"
+#define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+#include <private/android_filesystem_config.h>
+
+#include "NetdConstants.h"
+#include "FirewallController.h"
+
+const char* FirewallController::TABLE = "filter";
+
+const char* FirewallController::LOCAL_INPUT = "fw_INPUT";
+const char* FirewallController::LOCAL_OUTPUT = "fw_OUTPUT";
+const char* FirewallController::LOCAL_FORWARD = "fw_FORWARD";
+
+const char* FirewallController::LOCAL_DOZABLE = "fw_dozable";
+const char* FirewallController::LOCAL_STANDBY = "fw_standby";
+
+// ICMPv6 types that are required for any form of IPv6 connectivity to work. Note that because the
+// fw_dozable chain is called from both INPUT and OUTPUT, this includes both packets that we need
+// to be able to send (e.g., RS, NS), and packets that we need to receive (e.g., RA, NA).
+const char* FirewallController::ICMPV6_TYPES[] = {
+    "packet-too-big",
+    "router-solicitation",
+    "router-advertisement",
+    "neighbour-solicitation",
+    "neighbour-advertisement",
+    "redirect",
+};
+
+FirewallController::FirewallController(void) {
+    // If no rules are set, it's in BLACKLIST mode
+    mFirewallType = BLACKLIST;
+}
+
+int FirewallController::setupIptablesHooks(void) {
+    int res = 0;
+    // child chains are created but not attached, they will be attached explicitly.
+    FirewallType firewallType = getFirewallType(DOZABLE);
+    res |= createChain(LOCAL_DOZABLE, LOCAL_INPUT, firewallType);
+
+    firewallType = getFirewallType(STANDBY);
+    res |= createChain(LOCAL_STANDBY, LOCAL_INPUT, firewallType);
+
+    return res;
+}
+
+int FirewallController::enableFirewall(FirewallType ftype) {
+    int res = 0;
+    if (mFirewallType != ftype) {
+        // flush any existing rules
+        disableFirewall();
+
+        if (ftype == WHITELIST) {
+            // create default rule to drop all traffic
+            res |= execIptables(V4V6, "-A", LOCAL_INPUT, "-j", "DROP", NULL);
+            res |= execIptables(V4V6, "-A", LOCAL_OUTPUT, "-j", "REJECT", NULL);
+            res |= execIptables(V4V6, "-A", LOCAL_FORWARD, "-j", "REJECT", NULL);
+        }
+
+        // Set this after calling disableFirewall(), since it defaults to WHITELIST there
+        mFirewallType = ftype;
+    }
+    return res;
+}
+
+int FirewallController::disableFirewall(void) {
+    int res = 0;
+
+    mFirewallType = WHITELIST;
+
+    // flush any existing rules
+    res |= execIptables(V4V6, "-F", LOCAL_INPUT, NULL);
+    res |= execIptables(V4V6, "-F", LOCAL_OUTPUT, NULL);
+    res |= execIptables(V4V6, "-F", LOCAL_FORWARD, NULL);
+
+    return res;
+}
+
+int FirewallController::enableChildChains(ChildChain chain, bool enable) {
+    int res = 0;
+    const char* name;
+    switch(chain) {
+        case DOZABLE:
+            name = LOCAL_DOZABLE;
+            break;
+        case STANDBY:
+            name = LOCAL_STANDBY;
+            break;
+        default:
+            return res;
+    }
+
+    if (enable) {
+        res |= attachChain(name, LOCAL_INPUT);
+        res |= attachChain(name, LOCAL_OUTPUT);
+    } else {
+        res |= detachChain(name, LOCAL_INPUT);
+        res |= detachChain(name, LOCAL_OUTPUT);
+    }
+    return res;
+}
+
+int FirewallController::isFirewallEnabled(void) {
+    // TODO: verify that rules are still in place near top
+    return -1;
+}
+
+int FirewallController::setInterfaceRule(const char* iface, FirewallRule rule) {
+    if (mFirewallType == BLACKLIST) {
+        // Unsupported in BLACKLIST mode
+        return -1;
+    }
+
+    if (!isIfaceName(iface)) {
+        errno = ENOENT;
+        return -1;
+    }
+
+    const char* op;
+    if (rule == ALLOW) {
+        op = "-I";
+    } else {
+        op = "-D";
+    }
+
+    int res = 0;
+    res |= execIptables(V4V6, op, LOCAL_INPUT, "-i", iface, "-j", "RETURN", NULL);
+    res |= execIptables(V4V6, op, LOCAL_OUTPUT, "-o", iface, "-j", "RETURN", NULL);
+    return res;
+}
+
+int FirewallController::setEgressSourceRule(const char* addr, FirewallRule rule) {
+    if (mFirewallType == BLACKLIST) {
+        // Unsupported in BLACKLIST mode
+        return -1;
+    }
+
+    IptablesTarget target = V4;
+    if (strchr(addr, ':')) {
+        target = V6;
+    }
+
+    const char* op;
+    if (rule == ALLOW) {
+        op = "-I";
+    } else {
+        op = "-D";
+    }
+
+    int res = 0;
+    res |= execIptables(target, op, LOCAL_INPUT, "-d", addr, "-j", "RETURN", NULL);
+    res |= execIptables(target, op, LOCAL_OUTPUT, "-s", addr, "-j", "RETURN", NULL);
+    return res;
+}
+
+int FirewallController::setEgressDestRule(const char* addr, int protocol, int port,
+        FirewallRule rule) {
+    if (mFirewallType == BLACKLIST) {
+        // Unsupported in BLACKLIST mode
+        return -1;
+    }
+
+    IptablesTarget target = V4;
+    if (strchr(addr, ':')) {
+        target = V6;
+    }
+
+    char protocolStr[16];
+    sprintf(protocolStr, "%d", protocol);
+
+    char portStr[16];
+    sprintf(portStr, "%d", port);
+
+    const char* op;
+    if (rule == ALLOW) {
+        op = "-I";
+    } else {
+        op = "-D";
+    }
+
+    int res = 0;
+    res |= execIptables(target, op, LOCAL_INPUT, "-s", addr, "-p", protocolStr,
+            "--sport", portStr, "-j", "RETURN", NULL);
+    res |= execIptables(target, op, LOCAL_OUTPUT, "-d", addr, "-p", protocolStr,
+            "--dport", portStr, "-j", "RETURN", NULL);
+    return res;
+}
+
+FirewallType FirewallController::getFirewallType(ChildChain chain) {
+    switch(chain) {
+        case DOZABLE:
+            return WHITELIST;
+        case STANDBY:
+            return BLACKLIST;
+        case NONE:
+            return mFirewallType;
+        default:
+            return BLACKLIST;
+    }
+}
+
+int FirewallController::setUidRule(ChildChain chain, int uid, FirewallRule rule) {
+    char uidStr[16];
+    sprintf(uidStr, "%d", uid);
+
+    const char* op;
+    const char* target;
+    FirewallType firewallType = getFirewallType(chain);
+    if (firewallType == WHITELIST) {
+        target = "RETURN";
+        op = (rule == ALLOW)? "-I" : "-D";
+    } else { // BLACKLIST mode
+        target = "DROP";
+        op = (rule == DENY)? "-I" : "-D";
+    }
+
+    int res = 0;
+    switch(chain) {
+        case DOZABLE:
+            res |= execIptables(V4V6, op, LOCAL_DOZABLE, "-m", "owner", "--uid-owner",
+                    uidStr, "-j", target, NULL);
+            break;
+        case STANDBY:
+            res |= execIptables(V4V6, op, LOCAL_STANDBY, "-m", "owner", "--uid-owner",
+                    uidStr, "-j", target, NULL);
+            break;
+        case NONE:
+            res |= execIptables(V4V6, op, LOCAL_INPUT, "-m", "owner", "--uid-owner", uidStr,
+                    "-j", target, NULL);
+            res |= execIptables(V4V6, op, LOCAL_OUTPUT, "-m", "owner", "--uid-owner", uidStr,
+                    "-j", target, NULL);
+            break;
+        default:
+            ALOGW("Unknown child chain: %d", chain);
+            break;
+    }
+    return res;
+}
+
+int FirewallController::attachChain(const char* childChain, const char* parentChain) {
+    return execIptables(V4V6, "-t", TABLE, "-A", parentChain, "-j", childChain, NULL);
+}
+
+int FirewallController::detachChain(const char* childChain, const char* parentChain) {
+    return execIptables(V4V6, "-t", TABLE, "-D", parentChain, "-j", childChain, NULL);
+}
+
+int FirewallController::createChain(const char* childChain,
+        const char* parentChain, FirewallType type) {
+    // Order is important, otherwise later steps may fail.
+    execIptablesSilently(V4V6, "-t", TABLE, "-D", parentChain, "-j", childChain, NULL);
+    execIptablesSilently(V4V6, "-t", TABLE, "-F", childChain, NULL);
+    execIptablesSilently(V4V6, "-t", TABLE, "-X", childChain, NULL);
+    int res = 0;
+    res |= execIptables(V4V6, "-t", TABLE, "-N", childChain, NULL);
+    if (type == WHITELIST) {
+        // Allow ICMPv6 packets necessary to make IPv6 connectivity work. http://b/23158230 .
+        for (size_t i = 0; i < ARRAY_SIZE(ICMPV6_TYPES); i++) {
+            res |= execIptables(V6, "-A", childChain, "-p", "icmpv6", "--icmpv6-type",
+                    ICMPV6_TYPES[i], "-j", "RETURN", NULL);
+        }
+
+        // create default white list for system uid range
+        char uidStr[16];
+        sprintf(uidStr, "0-%d", AID_APP - 1);
+        res |= execIptables(V4V6, "-A", childChain, "-m", "owner", "--uid-owner",
+                uidStr, "-j", "RETURN", NULL);
+
+        // create default rule to drop all traffic
+        res |= execIptables(V4V6, "-A", childChain, "-j", "DROP", NULL);
+    }
+    return res;
+}
diff --git a/netd/server/FirewallController.h b/netd/server/FirewallController.h
new file mode 100644
index 0000000..34a8b9c
--- /dev/null
+++ b/netd/server/FirewallController.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#ifndef _FIREWALL_CONTROLLER_H
+#define _FIREWALL_CONTROLLER_H
+
+#include <string>
+
+enum FirewallRule { DENY, ALLOW };
+
+// WHITELIST means the firewall denies all by default, uids must be explicitly ALLOWed
+// BLACKLIST means the firewall allows all by default, uids must be explicitly DENYed
+
+enum FirewallType { WHITELIST, BLACKLIST };
+
+enum ChildChain { NONE, DOZABLE, STANDBY, INVALID_CHAIN };
+
+#define PROTOCOL_TCP 6
+#define PROTOCOL_UDP 17
+
+/*
+ * Simple firewall that drops all packets except those matching explicitly
+ * defined ALLOW rules.
+ */
+class FirewallController {
+public:
+    FirewallController();
+
+    int setupIptablesHooks(void);
+
+    int enableFirewall(FirewallType);
+    int disableFirewall(void);
+    int isFirewallEnabled(void);
+
+    /* Match traffic going in/out over the given iface. */
+    int setInterfaceRule(const char*, FirewallRule);
+    /* Match traffic coming-in-to or going-out-from given address. */
+    int setEgressSourceRule(const char*, FirewallRule);
+    /* Match traffic coming-in-from or going-out-to given address, port, and protocol. */
+    int setEgressDestRule(const char*, int, int, FirewallRule);
+    /* Match traffic owned by given UID. This is specific to a particular chain. */
+    int setUidRule(ChildChain, int, FirewallRule);
+
+    int enableChildChains(ChildChain, bool);
+
+    static const char* TABLE;
+
+    static const char* LOCAL_INPUT;
+    static const char* LOCAL_OUTPUT;
+    static const char* LOCAL_FORWARD;
+
+    static const char* LOCAL_DOZABLE;
+    static const char* LOCAL_STANDBY;
+
+    static const char* ICMPV6_TYPES[];
+
+private:
+    FirewallType mFirewallType;
+    int attachChain(const char*, const char*);
+    int detachChain(const char*, const char*);
+    int createChain(const char*, const char*, FirewallType);
+    FirewallType getFirewallType(ChildChain);
+};
+
+#endif
diff --git a/netd/server/FwmarkServer.cpp b/netd/server/FwmarkServer.cpp
new file mode 100644
index 0000000..530e96a
--- /dev/null
+++ b/netd/server/FwmarkServer.cpp
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2014 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 "FwmarkServer.h"
+
+#include "Fwmark.h"
+#include "FwmarkCommand.h"
+#include "NetworkController.h"
+#include "resolv_netid.h"
+
+#include <sys/socket.h>
+#include <unistd.h>
+
+FwmarkServer::FwmarkServer(NetworkController* networkController) :
+        SocketListener("fwmarkd", true), mNetworkController(networkController) {
+}
+
+bool FwmarkServer::onDataAvailable(SocketClient* client) {
+    int socketFd = -1;
+    int error = processClient(client, &socketFd);
+    if (socketFd >= 0) {
+        close(socketFd);
+    }
+
+    // Always send a response even if there were connection errors or read errors, so that we don't
+    // inadvertently cause the client to hang (which always waits for a response).
+    client->sendData(&error, sizeof(error));
+
+    // Always close the client connection (by returning false). This prevents a DoS attack where
+    // the client issues multiple commands on the same connection, never reading the responses,
+    // causing its receive buffer to fill up, and thus causing our client->sendData() to block.
+    return false;
+}
+
+int FwmarkServer::processClient(SocketClient* client, int* socketFd) {
+    FwmarkCommand command;
+
+    iovec iov;
+    iov.iov_base = &command;
+    iov.iov_len = sizeof(command);
+
+    msghdr message;
+    memset(&message, 0, sizeof(message));
+    message.msg_iov = &iov;
+    message.msg_iovlen = 1;
+
+    union {
+        cmsghdr cmh;
+        char cmsg[CMSG_SPACE(sizeof(*socketFd))];
+    } cmsgu;
+
+    memset(cmsgu.cmsg, 0, sizeof(cmsgu.cmsg));
+    message.msg_control = cmsgu.cmsg;
+    message.msg_controllen = sizeof(cmsgu.cmsg);
+
+    int messageLength = TEMP_FAILURE_RETRY(recvmsg(client->getSocket(), &message, 0));
+    if (messageLength <= 0) {
+        return -errno;
+    }
+
+    if (messageLength != sizeof(command)) {
+        return -EBADMSG;
+    }
+
+    Permission permission = mNetworkController->getPermissionForUser(client->getUid());
+
+    if (command.cmdId == FwmarkCommand::QUERY_USER_ACCESS) {
+        if ((permission & PERMISSION_SYSTEM) != PERMISSION_SYSTEM) {
+            return -EPERM;
+        }
+        return mNetworkController->checkUserNetworkAccess(command.uid, command.netId);
+    }
+
+    cmsghdr* const cmsgh = CMSG_FIRSTHDR(&message);
+    if (cmsgh && cmsgh->cmsg_level == SOL_SOCKET && cmsgh->cmsg_type == SCM_RIGHTS &&
+        cmsgh->cmsg_len == CMSG_LEN(sizeof(*socketFd))) {
+        memcpy(socketFd, CMSG_DATA(cmsgh), sizeof(*socketFd));
+    }
+
+    if (*socketFd < 0) {
+        return -EBADF;
+    }
+
+    Fwmark fwmark;
+    socklen_t fwmarkLen = sizeof(fwmark.intValue);
+    if (getsockopt(*socketFd, SOL_SOCKET, SO_MARK, &fwmark.intValue, &fwmarkLen) == -1) {
+        return -errno;
+    }
+
+    switch (command.cmdId) {
+        case FwmarkCommand::ON_ACCEPT: {
+            // Called after a socket accept(). The kernel would've marked the NetId and necessary
+            // permissions bits, so we just add the rest of the user's permissions here.
+            permission = static_cast<Permission>(permission | fwmark.permission);
+            break;
+        }
+
+        case FwmarkCommand::ON_CONNECT: {
+            // Called before a socket connect() happens. Set an appropriate NetId into the fwmark so
+            // that the socket routes consistently over that network. Do this even if the socket
+            // already has a NetId, so that calling connect() multiple times still works.
+            //
+            // But if the explicit bit was set, the existing NetId was explicitly preferred (and not
+            // a case of connect() being called multiple times). Don't reset the NetId in that case.
+            //
+            // An "appropriate" NetId is the NetId of a bypassable VPN that applies to the user, or
+            // failing that, the default network. We'll never set the NetId of a secure VPN here.
+            // See the comments in the implementation of getNetworkForConnect() for more details.
+            //
+            // If the protect bit is set, this could be either a system proxy (e.g.: the dns proxy
+            // or the download manager) acting on behalf of another user, or a VPN provider. If it's
+            // a proxy, we shouldn't reset the NetId. If it's a VPN provider, we should set the
+            // default network's NetId.
+            //
+            // There's no easy way to tell the difference between a proxy and a VPN app. We can't
+            // use PERMISSION_SYSTEM to identify the proxy because a VPN app may also have those
+            // permissions. So we use the following heuristic:
+            //
+            // If it's a proxy, but the existing NetId is not a VPN, that means the user (that the
+            // proxy is acting on behalf of) is not subject to a VPN, so the proxy must have picked
+            // the default network's NetId. So, it's okay to replace that with the current default
+            // network's NetId (which in all likelihood is the same).
+            //
+            // Conversely, if it's a VPN provider, the existing NetId cannot be a VPN. The only time
+            // we set a VPN's NetId into a socket without setting the explicit bit is here, in
+            // ON_CONNECT, but we won't do that if the socket has the protect bit set. If the VPN
+            // provider connect()ed (and got the VPN NetId set) and then called protect(), we
+            // would've unset the NetId in PROTECT_FROM_VPN below.
+            //
+            // So, overall (when the explicit bit is not set but the protect bit is set), if the
+            // existing NetId is a VPN, don't reset it. Else, set the default network's NetId.
+            if (!fwmark.explicitlySelected) {
+                if (!fwmark.protectedFromVpn) {
+                    fwmark.netId = mNetworkController->getNetworkForConnect(client->getUid());
+                } else if (!mNetworkController->isVirtualNetwork(fwmark.netId)) {
+                    fwmark.netId = mNetworkController->getDefaultNetwork();
+                }
+            }
+            break;
+        }
+
+        case FwmarkCommand::SELECT_NETWORK: {
+            fwmark.netId = command.netId;
+            if (command.netId == NETID_UNSET) {
+                fwmark.explicitlySelected = false;
+                fwmark.protectedFromVpn = false;
+                permission = PERMISSION_NONE;
+            } else {
+                if (int ret = mNetworkController->checkUserNetworkAccess(client->getUid(),
+                                                                         command.netId)) {
+                    return ret;
+                }
+                fwmark.explicitlySelected = true;
+                fwmark.protectedFromVpn = mNetworkController->canProtect(client->getUid());
+            }
+            break;
+        }
+
+        case FwmarkCommand::PROTECT_FROM_VPN: {
+            if (!mNetworkController->canProtect(client->getUid())) {
+                return -EPERM;
+            }
+            // If a bypassable VPN's provider app calls connect() and then protect(), it will end up
+            // with a socket that looks like that of a system proxy but is not (see comments for
+            // ON_CONNECT above). So, reset the NetId.
+            //
+            // In any case, it's appropriate that if the socket has an implicit VPN NetId mark, the
+            // PROTECT_FROM_VPN command should unset it.
+            if (!fwmark.explicitlySelected && mNetworkController->isVirtualNetwork(fwmark.netId)) {
+                fwmark.netId = mNetworkController->getDefaultNetwork();
+            }
+            fwmark.protectedFromVpn = true;
+            permission = static_cast<Permission>(permission | fwmark.permission);
+            break;
+        }
+
+        case FwmarkCommand::SELECT_FOR_USER: {
+            if ((permission & PERMISSION_SYSTEM) != PERMISSION_SYSTEM) {
+                return -EPERM;
+            }
+            fwmark.netId = mNetworkController->getNetworkForUser(command.uid);
+            fwmark.protectedFromVpn = true;
+            break;
+        }
+
+        default: {
+            // unknown command
+            return -EPROTO;
+        }
+    }
+
+    fwmark.permission = permission;
+
+    if (setsockopt(*socketFd, SOL_SOCKET, SO_MARK, &fwmark.intValue,
+                   sizeof(fwmark.intValue)) == -1) {
+        return -errno;
+    }
+
+    return 0;
+}
diff --git a/netd/server/FwmarkServer.h b/netd/server/FwmarkServer.h
new file mode 100644
index 0000000..12096be
--- /dev/null
+++ b/netd/server/FwmarkServer.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_SERVER_FWMARK_SERVER_H
+#define NETD_SERVER_FWMARK_SERVER_H
+
+#include "sysutils/SocketListener.h"
+
+class NetworkController;
+
+class FwmarkServer : public SocketListener {
+public:
+    explicit FwmarkServer(NetworkController* networkController);
+
+private:
+    // Overridden from SocketListener:
+    bool onDataAvailable(SocketClient* client);
+
+    // Returns 0 on success or a negative errno value on failure.
+    int processClient(SocketClient* client, int* socketFd);
+
+    NetworkController* const mNetworkController;
+};
+
+#endif  // NETD_SERVER_FWMARK_SERVER_H
diff --git a/netd/server/IdletimerController.cpp b/netd/server/IdletimerController.cpp
new file mode 100644
index 0000000..e6306fd
--- /dev/null
+++ b/netd/server/IdletimerController.cpp
@@ -0,0 +1,260 @@
+/*
+ * 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.
+ */
+
+/*
+ * MODUS OPERANDI
+ * --------------
+ *
+ * IPTABLES command sequence:
+ *
+ * iptables -F
+ *
+ * iptables -t raw -F idletimer_PREROUTING
+ * iptables -t mangle -F idletimer_POSTROUTING
+ *
+ *
+ * iptables -t raw -N idletimer_PREROUTING
+ * iptables -t mangle -N idletimer_POSTROUTING
+ *
+ * iptables -t raw -D PREROUTING -j idletimer_PREROUTING
+ * iptables -t mangle -D POSTROUTING -j idletimer_POSTROUTING
+ *
+ *
+ * iptables -t raw -I PREROUTING -j idletimer_PREROUTING
+ * iptables -t mangle -I POSTROUTING -j idletimer_POSTROUTING
+ *
+ * # For notifications to work the lable name must match the name of a valid interface.
+ * # If the label name does match an interface, the rules will be a no-op.
+ *
+ * iptables -t raw -A idletimer_PREROUTING -i rmnet0 -j IDLETIMER  --timeout 5 --label test-chain --send_nl_msg 1
+ * iptables -t mangle -A idletimer_POSTROUTING -o rmnet0 -j IDLETIMER  --timeout 5 --label test-chain --send_nl_msg 1
+ *
+ * iptables -nxvL -t raw
+ * iptables -nxvL -t mangle
+ *
+ * =================
+ *
+ * ndc command sequence
+ * ------------------
+ * ndc idletimer enable
+ * ndc idletimer add <iface> <timeout> <class label>
+ * ndc idletimer remove <iface> <timeout> <class label>
+ *
+ * Monitor effect on the iptables chains after each step using:
+ *     iptables -nxvL -t raw
+ *     iptables -nxvL -t mangle
+ *
+ * Remember that the timeout value has to be same at the time of the
+ * removal.
+ *
+ * =================
+ *
+ * Verifying the iptables rule
+ * ---------------------------
+ * We want to make sure the iptable rules capture every packet. It can be
+ * verified with tcpdump. First take a note of the pkts count for the two rules:
+ *
+ * adb shell iptables -t mangle -L idletimer_mangle_POSTROUTING -v && adb shell iptables -t raw -L idletimer_raw_PREROUTING -v
+ *
+ * And then, before any network traffics happen on the device, run tcpdump:
+ *
+ * adb shell tcpdump | tee tcpdump.log
+ *
+ * After a while run iptables commands again, you could then count the number
+ * of incoming and outgoing packets captured by tcpdump, and compare that with
+ * the numbers reported by iptables command. There shouldn't be too much
+ * difference on these numbers, i.e., with 2000 packets captured it should
+ * differ by less than 5.
+ *
+ * =================
+ *
+ * Note that currently if the name of the iface is incorrect, iptables
+ * will setup rules without checking if it is the name of a valid
+ * interface (although no notifications will ever be received).  It is
+ * the responsibility of code in Java land to ensure that the interface name
+ * is correct. The benefit of this, is that idletimers can be setup on
+ * interfaces than come and go.
+ *
+ * A remove should be called for each add command issued during cleanup, as duplicate
+ * entries of the rule may exist and will all have to removed.
+ *
+ */
+
+#define LOG_NDEBUG 0
+
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <cutils/properties.h>
+
+#define LOG_TAG "IdletimerController"
+#include <cutils/log.h>
+#include <logwrap/logwrap.h>
+
+#include "IdletimerController.h"
+#include "NetdConstants.h"
+
+const char* IdletimerController::LOCAL_RAW_PREROUTING = "idletimer_raw_PREROUTING";
+const char* IdletimerController::LOCAL_MANGLE_POSTROUTING = "idletimer_mangle_POSTROUTING";
+
+IdletimerController::IdletimerController() {
+}
+
+IdletimerController::~IdletimerController() {
+}
+/* return 0 or non-zero */
+int IdletimerController::runIpxtablesCmd(int argc, const char **argv) {
+    int resIpv4, resIpv6;
+
+    // Running for IPv4
+    argv[0] = IPTABLES_PATH;
+    resIpv4 = android_fork_execvp(argc, (char **)argv, NULL, false, false);
+
+    // Running for IPv6
+    argv[0] = IP6TABLES_PATH;
+    resIpv6 = android_fork_execvp(argc, (char **)argv, NULL, false, false);
+
+#if !LOG_NDEBUG
+    std::string full_cmd = argv[0];
+    argc--; argv++;
+    for (; argc; argc--, argv++) {
+        full_cmd += " ";
+        full_cmd += argv[0];
+    }
+    ALOGV("runCmd(%s) res_ipv4=%d, res_ipv6=%d", full_cmd.c_str(), resIpv4, resIpv6);
+#endif
+
+    return (resIpv4 == 0 && resIpv6 == 0) ? 0 : -1;
+}
+
+bool IdletimerController::setupIptablesHooks() {
+    return true;
+}
+
+int IdletimerController::setDefaults() {
+  int res;
+  const char *cmd1[] = {
+      NULL, // To be filled inside runIpxtablesCmd
+      "-w",
+      "-t",
+      "raw",
+      "-F",
+      LOCAL_RAW_PREROUTING
+  };
+  res = runIpxtablesCmd(ARRAY_SIZE(cmd1), cmd1);
+
+  if (res)
+    return res;
+
+  const char *cmd2[] = {
+      NULL, // To be filled inside runIpxtablesCmd
+      "-w",
+      "-t",
+      "mangle",
+      "-F",
+      LOCAL_MANGLE_POSTROUTING
+  };
+  res = runIpxtablesCmd(ARRAY_SIZE(cmd2), cmd2);
+
+  return res;
+}
+
+int IdletimerController::enableIdletimerControl() {
+    int res = setDefaults();
+    return res;
+}
+
+int IdletimerController::disableIdletimerControl() {
+    int res = setDefaults();
+    return res;
+}
+
+int IdletimerController::modifyInterfaceIdletimer(IptOp op, const char *iface,
+                                                  uint32_t timeout,
+                                                  const char *classLabel) {
+  int res;
+  char timeout_str[11]; //enough to store any 32-bit unsigned decimal
+
+  if (!isIfaceName(iface)) {
+    errno = ENOENT;
+    return -1;
+  }
+
+  snprintf(timeout_str, sizeof(timeout_str), "%u", timeout);
+
+  const char *cmd1[] = {
+      NULL, // To be filled inside runIpxtablesCmd
+      "-w",
+      "-t",
+      "raw",
+      (op == IptOpAdd) ? "-A" : "-D",
+      LOCAL_RAW_PREROUTING,
+      "-i",
+      iface,
+      "-j",
+      "IDLETIMER",
+      "--timeout",
+      timeout_str,
+      "--label",
+      classLabel,
+      "--send_nl_msg",
+      "1"
+  };
+  res = runIpxtablesCmd(ARRAY_SIZE(cmd1), cmd1);
+
+  if (res)
+    return res;
+
+  const char *cmd2[] = {
+      NULL, // To be filled inside runIpxtablesCmd
+      "-w",
+      "-t",
+      "mangle",
+      (op == IptOpAdd) ? "-A" : "-D",
+      LOCAL_MANGLE_POSTROUTING,
+      "-o",
+      iface,
+      "-j",
+      "IDLETIMER",
+      "--timeout",
+      timeout_str,
+      "--label",
+      classLabel,
+      "--send_nl_msg",
+      "1"
+  };
+  res = runIpxtablesCmd(ARRAY_SIZE(cmd2), cmd2);
+
+  return res;
+}
+
+int IdletimerController::addInterfaceIdletimer(const char *iface,
+                                               uint32_t timeout,
+                                               const char *classLabel) {
+  return modifyInterfaceIdletimer(IptOpAdd, iface, timeout, classLabel);
+}
+
+int IdletimerController::removeInterfaceIdletimer(const char *iface,
+                                                  uint32_t timeout,
+                                                  const char *classLabel) {
+  return modifyInterfaceIdletimer(IptOpDelete, iface, timeout, classLabel);
+}
diff --git a/netd/server/IdletimerController.h b/netd/server/IdletimerController.h
new file mode 100644
index 0000000..98a312e
--- /dev/null
+++ b/netd/server/IdletimerController.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+#ifndef _IDLETIMER_CONTROLLER_H
+#define _IDLETIMER_CONTROLLER_H
+
+class IdletimerController {
+public:
+
+    IdletimerController();
+    virtual ~IdletimerController();
+
+    int enableIdletimerControl();
+    int disableIdletimerControl();
+    int addInterfaceIdletimer(const char *iface, uint32_t timeout,
+                              const char *classLabel);
+    int removeInterfaceIdletimer(const char *iface, uint32_t timeout,
+                                 const char *classLabel);
+    bool setupIptablesHooks();
+
+    static const char* LOCAL_RAW_PREROUTING;
+    static const char* LOCAL_MANGLE_POSTROUTING;
+
+ private:
+    enum IptOp { IptOpAdd, IptOpDelete };
+    int setDefaults();
+    int runIpxtablesCmd(int argc, const char **cmd);
+    int modifyInterfaceIdletimer(IptOp op, const char *iface, uint32_t timeout,
+                                 const char *classLabel);
+};
+
+#endif
diff --git a/netd/server/InterfaceController.cpp b/netd/server/InterfaceController.cpp
new file mode 100644
index 0000000..c518fe6
--- /dev/null
+++ b/netd/server/InterfaceController.cpp
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <malloc.h>
+
+#define LOG_TAG "InterfaceController"
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <cutils/log.h>
+#include <logwrap/logwrap.h>
+
+#include "InterfaceController.h"
+#include "RouteController.h"
+
+using android::base::StringPrintf;
+using android::base::WriteStringToFile;
+
+namespace {
+
+const char ipv6_proc_path[] = "/proc/sys/net/ipv6/conf";
+
+const char ipv4_neigh_conf_dir[] = "/proc/sys/net/ipv4/neigh";
+
+const char ipv6_neigh_conf_dir[] = "/proc/sys/net/ipv6/neigh";
+
+const char sys_net_path[] = "/sys/class/net";
+
+const char wl_util_path[] = "/system/xbin/wlutil";
+
+bool isInterfaceName(const char *name) {
+    return strcmp(name, ".") &&
+            strcmp(name, "..") &&
+            strcmp(name, "default") &&
+            strcmp(name, "all");
+}
+
+int writeValueToPath(
+        const char* dirname, const char* subdirname, const char* basename,
+        const char* value) {
+    std::string path(StringPrintf("%s/%s/%s", dirname, subdirname, basename));
+    return WriteStringToFile(value, path) ? 0 : -1;
+}
+
+void setOnAllInterfaces(const char* dirname, const char* basename, const char* value) {
+    // Set the default value, which is used by any interfaces that are created in the future.
+    writeValueToPath(dirname, "default", basename, value);
+
+    // Set the value on all the interfaces that currently exist.
+    DIR* dir = opendir(dirname);
+    if (!dir) {
+        ALOGE("Can't list %s: %s", dirname, strerror(errno));
+        return;
+    }
+    dirent* d;
+    while ((d = readdir(dir))) {
+        if ((d->d_type != DT_DIR) || !isInterfaceName(d->d_name)) {
+            continue;
+        }
+        writeValueToPath(dirname, d->d_name, basename, value);
+    }
+    closedir(dir);
+}
+
+void setIPv6UseOutgoingInterfaceAddrsOnly(const char *value) {
+    setOnAllInterfaces(ipv6_proc_path, "use_oif_addrs_only", value);
+}
+
+}  // namespace
+
+InterfaceController::InterfaceController() {
+	// Initial IPv6 settings.
+	// By default, accept_ra is set to 1 (accept RAs unless forwarding is on) on all interfaces.
+	// This causes RAs to work or not work based on whether forwarding is on, and causes routes
+	// learned from RAs to go away when forwarding is turned on. Make this behaviour predictable
+	// by always setting accept_ra to 2.
+	setAcceptRA("2");
+
+	setAcceptRARouteTable(-RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX);
+
+	// Enable optimistic DAD for IPv6 addresses on all interfaces.
+	setIPv6OptimisticMode("1");
+
+	// Reduce the ARP/ND base reachable time from the default (30sec) to 15sec.
+	setBaseReachableTimeMs(15 * 1000);
+
+	// When sending traffic via a given interface use only addresses configured
+        // on that interface as possible source addresses.
+	setIPv6UseOutgoingInterfaceAddrsOnly("1");
+}
+
+InterfaceController::~InterfaceController() {
+}
+
+int InterfaceController::setEnableIPv6(const char *interface, const int on) {
+    if (!isIfaceName(interface)) {
+        errno = ENOENT;
+        return -1;
+    }
+    // When disable_ipv6 changes from 1 to 0, the kernel starts autoconf.
+    // When disable_ipv6 changes from 0 to 1, the kernel clears all autoconf
+    // addresses and routes and disables IPv6 on the interface.
+    const char *disable_ipv6 = on ? "0" : "1";
+    return writeValueToPath(ipv6_proc_path, interface, "disable_ipv6", disable_ipv6);
+}
+
+int InterfaceController::setIPv6PrivacyExtensions(const char *interface, const int on) {
+    if (!isIfaceName(interface)) {
+        errno = ENOENT;
+        return -1;
+    }
+    // 0: disable IPv6 privacy addresses
+    // 0: enable IPv6 privacy addresses and prefer them over non-privacy ones.
+    return writeValueToPath(ipv6_proc_path, interface, "use_tempaddr", on ? "2" : "0");
+}
+
+// Enables or disables IPv6 ND offload. This is useful for 464xlat on wifi, IPv6 tethering, and
+// generally implementing IPv6 neighbour discovery and duplicate address detection properly.
+// TODO: This should be implemented in wpa_supplicant via driver commands instead.
+int InterfaceController::setIPv6NdOffload(char* interface, const int on) {
+    // Only supported on Broadcom chipsets via wlutil for now.
+    if (access(wl_util_path, X_OK) == 0) {
+        const char *argv[] = {
+            wl_util_path,
+            "-a",
+            interface,
+            "ndoe",
+            on ? "1" : "0"
+        };
+        int ret = android_fork_execvp(ARRAY_SIZE(argv), const_cast<char**>(argv), NULL,
+                                      false, false);
+        ALOGD("%s ND offload on %s: %d (%s)",
+              (on ? "enabling" : "disabling"), interface, ret, strerror(errno));
+        return ret;
+    } else {
+        return 0;
+    }
+}
+
+void InterfaceController::setAcceptRA(const char *value) {
+    setOnAllInterfaces(ipv6_proc_path, "accept_ra", value);
+}
+
+// |tableOrOffset| is interpreted as:
+//     If == 0: default. Routes go into RT6_TABLE_MAIN.
+//     If > 0: user set. Routes go into the specified table.
+//     If < 0: automatic. The absolute value is intepreted as an offset and added to the interface
+//             ID to get the table. If it's set to -1000, routes from interface ID 5 will go into
+//             table 1005, etc.
+void InterfaceController::setAcceptRARouteTable(int tableOrOffset) {
+    std::string value(StringPrintf("%d", tableOrOffset));
+    setOnAllInterfaces(ipv6_proc_path, "accept_ra_rt_table", value.c_str());
+}
+
+int InterfaceController::setMtu(const char *interface, const char *mtu)
+{
+    if (!isIfaceName(interface)) {
+        errno = ENOENT;
+        return -1;
+    }
+    return writeValueToPath(sys_net_path, interface, "mtu", mtu);
+}
+
+void InterfaceController::setBaseReachableTimeMs(unsigned int millis) {
+    std::string value(StringPrintf("%u", millis));
+    setOnAllInterfaces(ipv4_neigh_conf_dir, "base_reachable_time_ms", value.c_str());
+    setOnAllInterfaces(ipv6_neigh_conf_dir, "base_reachable_time_ms", value.c_str());
+}
+
+void InterfaceController::setIPv6OptimisticMode(const char *value) {
+    setOnAllInterfaces(ipv6_proc_path, "optimistic_dad", value);
+    setOnAllInterfaces(ipv6_proc_path, "use_optimistic", value);
+}
diff --git a/netd/server/InterfaceController.h b/netd/server/InterfaceController.h
new file mode 100644
index 0000000..89728b1
--- /dev/null
+++ b/netd/server/InterfaceController.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef _INTERFACE_CONTROLLER_H
+#define _INTERFACE_CONTROLLER_H
+
+class InterfaceController {
+ public:
+	InterfaceController();
+	virtual ~InterfaceController();
+	int setEnableIPv6(const char *interface, const int on);
+	int setIPv6PrivacyExtensions(const char *interface, const int on);
+	int setIPv6NdOffload(char* interface, const int on);
+	int setMtu(const char *interface, const char *mtu);
+
+ private:
+	void setAcceptRA(const char* value);
+	void setAcceptRARouteTable(int tableOrOffset);
+	void setBaseReachableTimeMs(unsigned int millis);
+	void setIPv6OptimisticMode(const char *value);
+};
+
+#endif
diff --git a/netd/server/List.h b/netd/server/List.h
new file mode 100644
index 0000000..856ce26
--- /dev/null
+++ b/netd/server/List.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+// Templated list class.  Normally we'd use STL, but we don't have that.
+// This class mimics STL's interfaces.
+//
+// Objects are copied into the list with the '=' operator or with copy-
+// construction, so if the compiler's auto-generated versions won't work for
+// you, define your own.
+//
+// The only class you want to use from here is "List".
+//
+#ifndef _NETD_LIST_H
+#define _NETD_LIST_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace android {
+namespace netd {
+
+/*
+ * Doubly-linked list.  Instantiate with "List<MyClass> myList".
+ *
+ * Objects added to the list are copied using the assignment operator,
+ * so this must be defined.
+ */
+template<typename T> 
+class List 
+{
+protected:
+    /*
+     * One element in the list.
+     */
+    class _Node {
+    public:
+        explicit _Node(const T& val) : mVal(val) {}
+        ~_Node() {}
+        inline T& getRef() { return mVal; }
+        inline const T& getRef() const { return mVal; }
+        inline _Node* getPrev() const { return mpPrev; }
+        inline _Node* getNext() const { return mpNext; }
+        inline void setVal(const T& val) { mVal = val; }
+        inline void setPrev(_Node* ptr) { mpPrev = ptr; }
+        inline void setNext(_Node* ptr) { mpNext = ptr; }
+    private:
+        friend class List;
+        friend class _ListIterator;
+        T           mVal;
+        _Node*      mpPrev;
+        _Node*      mpNext;
+    };
+
+    /*
+     * Iterator for walking through the list.
+     */
+    
+    template <typename TYPE>
+    struct CONST_ITERATOR {
+        typedef _Node const * NodePtr;
+        typedef const TYPE Type;
+    };
+    
+    template <typename TYPE>
+    struct NON_CONST_ITERATOR {
+        typedef _Node* NodePtr;
+        typedef TYPE Type;
+    };
+    
+    template<
+        typename U,
+        template <class> class Constness
+    > 
+    class _ListIterator {
+        typedef _ListIterator<U, Constness>     _Iter;
+        typedef typename Constness<U>::NodePtr  _NodePtr;
+        typedef typename Constness<U>::Type     _Type;
+
+        explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {}
+
+    public:
+        _ListIterator() {}
+        _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {}
+        ~_ListIterator() {}
+        
+        // this will handle conversions from iterator to const_iterator
+        // (and also all convertible iterators)
+        // Here, in this implementation, the iterators can be converted
+        // if the nodes can be converted
+        template<typename V> explicit 
+        _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {}
+        
+
+        /*
+         * Dereference operator.  Used to get at the juicy insides.
+         */
+        _Type& operator*() const { return mpNode->getRef(); }
+        _Type* operator->() const { return &(mpNode->getRef()); }
+
+        /*
+         * Iterator comparison.
+         */
+        inline bool operator==(const _Iter& right) const { 
+            return mpNode == right.mpNode; }
+        
+        inline bool operator!=(const _Iter& right) const { 
+            return mpNode != right.mpNode; }
+
+        /*
+         * handle comparisons between iterator and const_iterator
+         */
+        template<typename OTHER>
+        inline bool operator==(const OTHER& right) const { 
+            return mpNode == right.mpNode; }
+        
+        template<typename OTHER>
+        inline bool operator!=(const OTHER& right) const { 
+            return mpNode != right.mpNode; }
+
+        /*
+         * Incr/decr, used to move through the list.
+         */
+        inline _Iter& operator++() {     // pre-increment
+            mpNode = mpNode->getNext();
+            return *this;
+        }
+        const _Iter operator++(int) {    // post-increment
+            _Iter tmp(*this);
+            mpNode = mpNode->getNext();
+            return tmp;
+        }
+        inline _Iter& operator--() {     // pre-increment
+            mpNode = mpNode->getPrev();
+            return *this;
+        }
+        const _Iter operator--(int) {   // post-increment
+            _Iter tmp(*this);
+            mpNode = mpNode->getPrev();
+            return tmp;
+        }
+
+        inline _NodePtr getNode() const { return mpNode; }
+
+        _NodePtr mpNode;    /* should be private, but older gcc fails */
+    private:
+        friend class List;
+    };
+
+public:
+    List() {
+        prep();
+    }
+    List(const List<T>& src) {      // copy-constructor
+        prep();
+        insert(begin(), src.begin(), src.end());
+    }
+    virtual ~List() {
+        clear();
+        delete[] (unsigned char*) mpMiddle;
+    }
+
+    typedef _ListIterator<T, NON_CONST_ITERATOR> iterator;
+    typedef _ListIterator<T, CONST_ITERATOR> const_iterator;
+
+    List<T>& operator=(const List<T>& right);
+
+    /* returns true if the list is empty */
+    inline bool empty() const { return mpMiddle->getNext() == mpMiddle; }
+
+    /* return #of elements in list */
+    size_t size() const {
+        return size_t(distance(begin(), end()));
+    }
+
+    /*
+     * Return the first element or one past the last element.  The
+     * _Node* we're returning is converted to an "iterator" by a
+     * constructor in _ListIterator.
+     */
+    inline iterator begin() { 
+        return iterator(mpMiddle->getNext()); 
+    }
+    inline const_iterator begin() const { 
+        return const_iterator(const_cast<_Node const*>(mpMiddle->getNext())); 
+    }
+    inline iterator end() { 
+        return iterator(mpMiddle); 
+    }
+    inline const_iterator end() const { 
+        return const_iterator(const_cast<_Node const*>(mpMiddle)); 
+    }
+
+    /* add the object to the head or tail of the list */
+    void push_front(const T& val) { insert(begin(), val); }
+    void push_back(const T& val) { insert(end(), val); }
+
+    /* insert before the current node; returns iterator at new node */
+    iterator insert(iterator posn, const T& val) 
+    {
+        _Node* newNode = new _Node(val);        // alloc & copy-construct
+        newNode->setNext(posn.getNode());
+        newNode->setPrev(posn.getNode()->getPrev());
+        posn.getNode()->getPrev()->setNext(newNode);
+        posn.getNode()->setPrev(newNode);
+        return iterator(newNode);
+    }
+
+    /* insert a range of elements before the current node */
+    void insert(iterator posn, const_iterator first, const_iterator last) {
+        for ( ; first != last; ++first)
+            insert(posn, *first);
+    }
+
+    /* remove one entry; returns iterator at next node */
+    iterator erase(iterator posn) {
+        _Node* pNext = posn.getNode()->getNext();
+        _Node* pPrev = posn.getNode()->getPrev();
+        pPrev->setNext(pNext);
+        pNext->setPrev(pPrev);
+        delete posn.getNode();
+        return iterator(pNext);
+    }
+
+    /* remove a range of elements */
+    iterator erase(iterator first, iterator last) {
+        while (first != last)
+            erase(first++);     // don't erase than incr later!
+        return iterator(last);
+    }
+
+    /* remove all contents of the list */
+    void clear() {
+        _Node* pCurrent = mpMiddle->getNext();
+        _Node* pNext;
+
+        while (pCurrent != mpMiddle) {
+            pNext = pCurrent->getNext();
+            delete pCurrent;
+            pCurrent = pNext;
+        }
+        mpMiddle->setPrev(mpMiddle);
+        mpMiddle->setNext(mpMiddle);
+    }
+
+    /*
+     * Measure the distance between two iterators.  On exist, "first"
+     * will be equal to "last".  The iterators must refer to the same
+     * list.
+     *
+     * FIXME: This is actually a generic iterator function. It should be a 
+     * template function at the top-level with specializations for things like
+     * vector<>, which can just do pointer math). Here we limit it to
+     * _ListIterator of the same type but different constness.
+     */
+    template<
+        typename U,
+        template <class> class CL,
+        template <class> class CR
+    > 
+    ptrdiff_t distance(
+            _ListIterator<U, CL> first, _ListIterator<U, CR> last) const 
+    {
+        ptrdiff_t count = 0;
+        while (first != last) {
+            ++first;
+            ++count;
+        }
+        return count;
+    }
+
+private:
+    /*
+     * I want a _Node but don't need it to hold valid data.  More
+     * to the point, I don't want T's constructor to fire, since it
+     * might have side-effects or require arguments.  So, we do this
+     * slightly uncouth storage alloc.
+     */
+    void prep() {
+        mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];
+        mpMiddle->setPrev(mpMiddle);
+        mpMiddle->setNext(mpMiddle);
+    }
+
+    /*
+     * This node plays the role of "pointer to head" and "pointer to tail".
+     * It sits in the middle of a circular list of nodes.  The iterator
+     * runs around the circle until it encounters this one.
+     */
+    _Node*      mpMiddle;
+};
+
+/*
+ * Assignment operator.
+ *
+ * The simplest way to do this would be to clear out the target list and
+ * fill it with the source.  However, we can speed things along by
+ * re-using existing elements.
+ */
+template<class T>
+List<T>& List<T>::operator=(const List<T>& right)
+{
+    if (this == &right)
+        return *this;       // self-assignment
+    iterator firstDst = begin();
+    iterator lastDst = end();
+    const_iterator firstSrc = right.begin();
+    const_iterator lastSrc = right.end();
+    while (firstSrc != lastSrc && firstDst != lastDst)
+        *firstDst++ = *firstSrc++;
+    if (firstSrc == lastSrc)        // ran out of elements in source?
+        erase(firstDst, lastDst);   // yes, erase any extras
+    else
+        insert(lastDst, firstSrc, lastSrc);     // copy remaining over
+    return *this;
+}
+
+}; // namespace netd
+}; // namespace android
+
+#endif // _NETD_LIST_H
diff --git a/netd/server/LocalNetwork.cpp b/netd/server/LocalNetwork.cpp
new file mode 100644
index 0000000..ba0b21e
--- /dev/null
+++ b/netd/server/LocalNetwork.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 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 "LocalNetwork.h"
+
+#include "RouteController.h"
+
+#define LOG_TAG "Netd"
+#include "log/log.h"
+
+LocalNetwork::LocalNetwork(unsigned netId) : Network(netId) {
+}
+
+LocalNetwork::~LocalNetwork() {
+}
+
+Network::Type LocalNetwork::getType() const {
+    return LOCAL;
+}
+
+int LocalNetwork::addInterface(const std::string& interface) {
+    if (hasInterface(interface)) {
+        return 0;
+    }
+    if (int ret = RouteController::addInterfaceToLocalNetwork(mNetId, interface.c_str())) {
+        ALOGE("failed to add interface %s to local netId %u", interface.c_str(), mNetId);
+        return ret;
+    }
+    mInterfaces.insert(interface);
+    return 0;
+}
+
+int LocalNetwork::removeInterface(const std::string& interface) {
+    if (!hasInterface(interface)) {
+        return 0;
+    }
+    if (int ret = RouteController::removeInterfaceFromLocalNetwork(mNetId, interface.c_str())) {
+        ALOGE("failed to remove interface %s from local netId %u", interface.c_str(), mNetId);
+        return ret;
+    }
+    mInterfaces.erase(interface);
+    return 0;
+}
diff --git a/netd/server/LocalNetwork.h b/netd/server/LocalNetwork.h
new file mode 100644
index 0000000..89a67f4
--- /dev/null
+++ b/netd/server/LocalNetwork.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_SERVER_LOCAL_NETWORK_H
+#define NETD_SERVER_LOCAL_NETWORK_H
+
+#include "Network.h"
+
+class LocalNetwork : public Network {
+public:
+    explicit LocalNetwork(unsigned netId);
+    virtual ~LocalNetwork();
+
+private:
+    Type getType() const override;
+    int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+    int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+};
+
+#endif  // NETD_SERVER_LOCAL_NETWORK_H
diff --git a/netd/server/MDnsSdListener.cpp b/netd/server/MDnsSdListener.cpp
new file mode 100644
index 0000000..4becbe8
--- /dev/null
+++ b/netd/server/MDnsSdListener.cpp
@@ -0,0 +1,767 @@
+/*
+ * 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.
+ */
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <errno.h>
+#include <linux/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <string.h>
+
+#define LOG_TAG "MDnsDS"
+#define DBG 1
+#define VDBG 1
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <sysutils/SocketClient.h>
+
+#include "MDnsSdListener.h"
+#include "ResponseCode.h"
+
+#define MDNS_SERVICE_NAME "mdnsd"
+#define MDNS_SERVICE_STATUS "init.svc.mdnsd"
+
+MDnsSdListener::MDnsSdListener() :
+                 FrameworkListener("mdns", true) {
+    Monitor *m = new Monitor();
+    registerCmd(new Handler(m, this));
+}
+
+MDnsSdListener::Handler::Handler(Monitor *m, MDnsSdListener *listener) :
+   NetdCommand("mdnssd") {
+   if (DBG) ALOGD("MDnsSdListener::Hander starting up");
+   mMonitor = m;
+   mListener = listener;
+}
+
+MDnsSdListener::Handler::~Handler() {}
+
+void MDnsSdListener::Handler::discover(SocketClient *cli,
+        const char *iface,
+        const char *regType,
+        const char *domain,
+        const int requestId,
+        const int requestFlags) {
+    if (VDBG) {
+        ALOGD("discover(%s, %s, %s, %d, %d)", iface, regType, domain, requestId,
+                requestFlags);
+    }
+    Context *context = new Context(requestId, mListener);
+    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
+    if (ref == NULL) {
+        ALOGE("requestId %d already in use during discover call", requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "RequestId already in use during discover call", false);
+        return;
+    }
+    if (VDBG) ALOGD("using ref %p", ref);
+    DNSServiceFlags nativeFlags = iToFlags(requestFlags);
+    int interfaceInt = ifaceNameToI(iface);
+
+    DNSServiceErrorType result = DNSServiceBrowse(ref, nativeFlags, interfaceInt, regType,
+            domain, &MDnsSdListenerDiscoverCallback, context);
+    if (result != kDNSServiceErr_NoError) {
+        ALOGE("Discover request %d got an error from DNSServiceBrowse %d", requestId, result);
+        mMonitor->freeServiceRef(requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "Discover request got an error from DNSServiceBrowse", false);
+        return;
+    }
+    mMonitor->startMonitoring(requestId);
+    if (VDBG) ALOGD("discover successful");
+    cli->sendMsg(ResponseCode::CommandOkay, "Discover operation started", false);
+    return;
+}
+
+void MDnsSdListenerDiscoverCallback(DNSServiceRef /* sdRef */, DNSServiceFlags flags,
+        uint32_t /* interfaceIndex */, DNSServiceErrorType errorCode, const char *serviceName,
+        const char *regType, const char *replyDomain, void *inContext) {
+    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
+    char *msg;
+    int refNumber = context->mRefNumber;
+
+    if (errorCode != kDNSServiceErr_NoError) {
+        asprintf(&msg, "%d %d", refNumber, errorCode);
+        context->mListener->sendBroadcast(ResponseCode::ServiceDiscoveryFailed, msg, false);
+        if (DBG) ALOGE("discover failure for %d, error= %d", refNumber, errorCode);
+    } else {
+        int respCode;
+        char *quotedServiceName = SocketClient::quoteArg(serviceName);
+        if (flags & kDNSServiceFlagsAdd) {
+            if (VDBG) {
+                ALOGD("Discover found new serviceName %s, regType %s and domain %s for %d",
+                        serviceName, regType, replyDomain, refNumber);
+            }
+            respCode = ResponseCode::ServiceDiscoveryServiceAdded;
+        } else {
+            if (VDBG) {
+                ALOGD("Discover lost serviceName %s, regType %s and domain %s for %d",
+                        serviceName, regType, replyDomain, refNumber);
+            }
+            respCode = ResponseCode::ServiceDiscoveryServiceRemoved;
+        }
+        asprintf(&msg, "%d %s %s %s", refNumber, quotedServiceName, regType, replyDomain);
+        free(quotedServiceName);
+        context->mListener->sendBroadcast(respCode, msg, false);
+    }
+    free(msg);
+}
+
+void MDnsSdListener::Handler::stop(SocketClient *cli, int argc, char **argv, const char *str) {
+    if (argc != 3) {
+        char *msg;
+        asprintf(&msg, "Invalid number of arguments to %s", str);
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return;
+    }
+    int requestId = atoi(argv[2]);
+    DNSServiceRef *ref = mMonitor->lookupServiceRef(requestId);
+    if (ref == NULL) {
+        if (DBG) ALOGE("%s stop used unknown requestId %d", str, requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError, "Unknown requestId", false);
+        return;
+    }
+    if (VDBG) ALOGD("Stopping %s with ref %p", str, ref);
+    DNSServiceRefDeallocate(*ref);
+    mMonitor->freeServiceRef(requestId);
+    char *msg;
+    asprintf(&msg, "%s stopped", str);
+    cli->sendMsg(ResponseCode::CommandOkay, msg, false);
+    free(msg);
+}
+
+void MDnsSdListener::Handler::serviceRegister(SocketClient *cli, int requestId,
+        const char *interfaceName, const char *serviceName, const char *serviceType,
+        const char *domain, const char *host, int port, int txtLen, void *txtRecord) {
+    if (VDBG) {
+        ALOGD("serviceRegister(%d, %s, %s, %s, %s, %s, %d, %d, <binary>)", requestId,
+                interfaceName, serviceName, serviceType, domain, host, port, txtLen);
+    }
+    Context *context = new Context(requestId, mListener);
+    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
+    port = htons(port);
+    if (ref == NULL) {
+        ALOGE("requestId %d already in use during register call", requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "RequestId already in use during register call", false);
+        return;
+    }
+    DNSServiceFlags nativeFlags = 0;
+    int interfaceInt = ifaceNameToI(interfaceName);
+    DNSServiceErrorType result = DNSServiceRegister(ref, interfaceInt, nativeFlags, serviceName,
+            serviceType, domain, host, port, txtLen, txtRecord, &MDnsSdListenerRegisterCallback,
+            context);
+    if (result != kDNSServiceErr_NoError) {
+        ALOGE("service register request %d got an error from DNSServiceRegister %d", requestId,
+                result);
+        mMonitor->freeServiceRef(requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "serviceRegister request got an error from DNSServiceRegister", false);
+        return;
+    }
+    mMonitor->startMonitoring(requestId);
+    if (VDBG) ALOGD("serviceRegister successful");
+    cli->sendMsg(ResponseCode::CommandOkay, "serviceRegister started", false);
+    return;
+}
+
+void MDnsSdListenerRegisterCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
+        DNSServiceErrorType errorCode, const char *serviceName, const char * /* regType */,
+        const char * /* domain */, void *inContext) {
+    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
+    char *msg;
+    int refNumber = context->mRefNumber;
+    if (errorCode != kDNSServiceErr_NoError) {
+        asprintf(&msg, "%d %d", refNumber, errorCode);
+        context->mListener->sendBroadcast(ResponseCode::ServiceRegistrationFailed, msg, false);
+        if (DBG) ALOGE("register failure for %d, error= %d", refNumber, errorCode);
+    } else {
+        char *quotedServiceName = SocketClient::quoteArg(serviceName);
+        asprintf(&msg, "%d %s", refNumber, quotedServiceName);
+        free(quotedServiceName);
+        context->mListener->sendBroadcast(ResponseCode::ServiceRegistrationSucceeded, msg, false);
+        if (VDBG) ALOGD("register succeeded for %d as %s", refNumber, serviceName);
+    }
+    free(msg);
+}
+
+
+void MDnsSdListener::Handler::resolveService(SocketClient *cli, int requestId,
+        const char *interfaceName, const char *serviceName, const char *regType,
+        const char *domain) {
+    if (VDBG) {
+        ALOGD("resolveService(%d, %s, %s, %s, %s)", requestId, interfaceName,
+                serviceName, regType, domain);
+    }
+    Context *context = new Context(requestId, mListener);
+    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
+    if (ref == NULL) {
+        ALOGE("request Id %d already in use during resolve call", requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "RequestId already in use during resolve call", false);
+        return;
+    }
+    DNSServiceFlags nativeFlags = 0;
+    int interfaceInt = ifaceNameToI(interfaceName);
+    DNSServiceErrorType result = DNSServiceResolve(ref, nativeFlags, interfaceInt, serviceName,
+            regType, domain, &MDnsSdListenerResolveCallback, context);
+    if (result != kDNSServiceErr_NoError) {
+        ALOGE("service resolve request %d got an error from DNSServiceResolve %d", requestId,
+                result);
+        mMonitor->freeServiceRef(requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "resolveService got an error from DNSServiceResolve", false);
+        return;
+    }
+    mMonitor->startMonitoring(requestId);
+    if (VDBG) ALOGD("resolveService successful");
+    cli->sendMsg(ResponseCode::CommandOkay, "resolveService started", false);
+    return;
+}
+
+void MDnsSdListenerResolveCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
+        uint32_t /* interface */, DNSServiceErrorType errorCode, const char *fullname,
+        const char *hosttarget, uint16_t port, uint16_t txtLen,
+        const unsigned char * /* txtRecord */, void *inContext) {
+    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
+    char *msg;
+    int refNumber = context->mRefNumber;
+    port = ntohs(port);
+    if (errorCode != kDNSServiceErr_NoError) {
+        asprintf(&msg, "%d %d", refNumber, errorCode);
+        context->mListener->sendBroadcast(ResponseCode::ServiceResolveFailed, msg, false);
+        if (DBG) ALOGE("resolve failure for %d, error= %d", refNumber, errorCode);
+    } else {
+        char *quotedFullName = SocketClient::quoteArg(fullname);
+        char *quotedHostTarget = SocketClient::quoteArg(hosttarget);
+        asprintf(&msg, "%d %s %s %d %d", refNumber, quotedFullName, quotedHostTarget, port, txtLen);
+        free(quotedFullName);
+        free(quotedHostTarget);
+        context->mListener->sendBroadcast(ResponseCode::ServiceResolveSuccess, msg, false);
+        if (VDBG) {
+            ALOGD("resolve succeeded for %d finding %s at %s:%d with txtLen %d",
+                    refNumber, fullname, hosttarget, port, txtLen);
+        }
+    }
+    free(msg);
+}
+
+void MDnsSdListener::Handler::getAddrInfo(SocketClient *cli, int requestId,
+        const char *interfaceName, uint32_t protocol, const char *hostname) {
+    if (VDBG) ALOGD("getAddrInfo(%d, %s %d, %s)", requestId, interfaceName, protocol, hostname);
+    Context *context = new Context(requestId, mListener);
+    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
+    if (ref == NULL) {
+        ALOGE("request ID %d already in use during getAddrInfo call", requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "RequestId already in use during getAddrInfo call", false);
+        return;
+    }
+    DNSServiceFlags nativeFlags = 0;
+    int interfaceInt = ifaceNameToI(interfaceName);
+    DNSServiceErrorType result = DNSServiceGetAddrInfo(ref, nativeFlags, interfaceInt, protocol,
+            hostname, &MDnsSdListenerGetAddrInfoCallback, context);
+    if (result != kDNSServiceErr_NoError) {
+        ALOGE("getAddrInfo request %d got an error from DNSServiceGetAddrInfo %d", requestId,
+                result);
+        mMonitor->freeServiceRef(requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "getAddrInfo request got an error from DNSServiceGetAddrInfo", false);
+        return;
+    }
+    mMonitor->startMonitoring(requestId);
+    if (VDBG) ALOGD("getAddrInfo successful");
+    cli->sendMsg(ResponseCode::CommandOkay, "getAddrInfo started", false);
+    return;
+}
+
+void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
+        uint32_t /* interface */, DNSServiceErrorType errorCode, const char *hostname,
+        const struct sockaddr *const sa, uint32_t ttl, void *inContext) {
+    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
+    int refNumber = context->mRefNumber;
+
+    if (errorCode != kDNSServiceErr_NoError) {
+        char *msg;
+        asprintf(&msg, "%d %d", refNumber, errorCode);
+        context->mListener->sendBroadcast(ResponseCode::ServiceGetAddrInfoFailed, msg, false);
+        if (DBG) ALOGE("getAddrInfo failure for %d, error= %d", refNumber, errorCode);
+        free(msg);
+    } else {
+        char addr[INET6_ADDRSTRLEN];
+        char *msg;
+        char *quotedHostname = SocketClient::quoteArg(hostname);
+        if (sa->sa_family == AF_INET) {
+            inet_ntop(sa->sa_family, &(((struct sockaddr_in *)sa)->sin_addr), addr, sizeof(addr));
+        } else {
+            inet_ntop(sa->sa_family, &(((struct sockaddr_in6 *)sa)->sin6_addr), addr, sizeof(addr));
+        }
+        asprintf(&msg, "%d %s %d %s", refNumber, quotedHostname, ttl, addr);
+        free(quotedHostname);
+        context->mListener->sendBroadcast(ResponseCode::ServiceGetAddrInfoSuccess, msg, false);
+        if (VDBG) {
+            ALOGD("getAddrInfo succeeded for %d: %s", refNumber, msg);
+        }
+        free(msg);
+    }
+}
+
+void MDnsSdListener::Handler::setHostname(SocketClient *cli, int requestId,
+        const char *hostname) {
+    if (VDBG) ALOGD("setHostname(%d, %s)", requestId, hostname);
+    Context *context = new Context(requestId, mListener);
+    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
+    if (ref == NULL) {
+        ALOGE("request Id %d already in use during setHostname call", requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "RequestId already in use during setHostname call", false);
+        return;
+    }
+    DNSServiceFlags nativeFlags = 0;
+    DNSServiceErrorType result = DNSSetHostname(ref, nativeFlags, hostname,
+            &MDnsSdListenerSetHostnameCallback, context);
+    if (result != kDNSServiceErr_NoError) {
+        ALOGE("setHostname request %d got an error from DNSSetHostname %d", requestId, result);
+        mMonitor->freeServiceRef(requestId);
+        cli->sendMsg(ResponseCode::CommandParameterError,
+                "setHostname got an error from DNSSetHostname", false);
+        return;
+    }
+    mMonitor->startMonitoring(requestId);
+    if (VDBG) ALOGD("setHostname successful");
+    cli->sendMsg(ResponseCode::CommandOkay, "setHostname started", false);
+    return;
+}
+
+void MDnsSdListenerSetHostnameCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
+        DNSServiceErrorType errorCode, const char *hostname, void *inContext) {
+    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
+    char *msg;
+    int refNumber = context->mRefNumber;
+    if (errorCode != kDNSServiceErr_NoError) {
+        asprintf(&msg, "%d %d", refNumber, errorCode);
+        context->mListener->sendBroadcast(ResponseCode::ServiceSetHostnameFailed, msg, false);
+        if (DBG) ALOGE("setHostname failure for %d, error= %d", refNumber, errorCode);
+    } else {
+        char *quotedHostname = SocketClient::quoteArg(hostname);
+        asprintf(&msg, "%d %s", refNumber, quotedHostname);
+        free(quotedHostname);
+        context->mListener->sendBroadcast(ResponseCode::ServiceSetHostnameSuccess, msg, false);
+        if (VDBG) ALOGD("setHostname succeeded for %d.  Set to %s", refNumber, hostname);
+    }
+    free(msg);
+}
+
+
+int MDnsSdListener::Handler::ifaceNameToI(const char * /* iface */) {
+    return 0;
+}
+
+const char *MDnsSdListener::Handler::iToIfaceName(int /* i */) {
+    return NULL;
+}
+
+DNSServiceFlags MDnsSdListener::Handler::iToFlags(int /* i */) {
+    return 0;
+}
+
+int MDnsSdListener::Handler::flagsToI(DNSServiceFlags /* flags */) {
+    return 0;
+}
+
+int MDnsSdListener::Handler::runCommand(SocketClient *cli,
+                                        int argc, char **argv) {
+    if (argc < 2) {
+        char* msg = NULL;
+        asprintf( &msg, "Invalid number of arguments to mdnssd: %i", argc);
+        ALOGW("%s", msg);
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    char* cmd = argv[1];
+
+    if (strcmp(cmd, "discover") == 0) {
+        if (argc != 4) {
+            cli->sendMsg(ResponseCode::CommandParameterError,
+                    "Invalid number of arguments to mdnssd discover", false);
+            return 0;
+        }
+        int requestId = atoi(argv[2]);
+        char *serviceType = argv[3];
+
+        discover(cli, NULL, serviceType, NULL, requestId, 0);
+    } else if (strcmp(cmd, "stop-discover") == 0) {
+        stop(cli, argc, argv, "discover");
+    } else if (strcmp(cmd, "register") == 0) {
+        if (argc < 6) {
+            cli->sendMsg(ResponseCode::CommandParameterError,
+                    "Invalid number of arguments to mdnssd register", false);
+            return 0;
+        }
+        int requestId = atoi(argv[2]);
+        char *serviceName = argv[3];
+        char *serviceType = argv[4];
+        int port = atoi(argv[5]);
+        char *interfaceName = NULL; // will use all
+        char *domain = NULL;        // will use default
+        char *host = NULL;          // will use default hostname
+        unsigned char txtRecord[2048] = "";
+        unsigned char *ptr = txtRecord;
+        for (int i = 6; i < argc; ++i) {
+          int dataLength = strlen(argv[i]);
+          if (dataLength < 1) {
+            continue;
+          }
+          if (dataLength > 255) {
+            cli->sendMsg(ResponseCode::CommandParameterError,
+                    "TXT record fields must not be longer than 255 characters", false);
+            return 0;
+          }
+          if (ptr + dataLength + 1 > txtRecord + sizeof(txtRecord)) {
+            cli->sendMsg(ResponseCode::CommandParameterError,
+                    "Total length of TXT record must be smaller than 2048 bytes", false);
+            return 0;
+          }
+          *ptr++ = dataLength;
+          strcpy( (char*) ptr, argv[i]);
+          ptr += dataLength;
+        }
+        serviceRegister(cli, requestId, interfaceName, serviceName,
+                serviceType, domain, host, port, ptr - txtRecord, txtRecord);
+    } else if (strcmp(cmd, "stop-register") == 0) {
+        stop(cli, argc, argv, "register");
+    } else if (strcmp(cmd, "resolve") == 0) {
+        if (argc != 6) {
+            cli->sendMsg(ResponseCode::CommandParameterError,
+                    "Invalid number of arguments to mdnssd resolve", false);
+            return 0;
+        }
+        int requestId = atoi(argv[2]);
+        char *interfaceName = NULL;  // will use all
+        char *serviceName = argv[3];
+        char *regType = argv[4];
+        char *domain = argv[5];
+        resolveService(cli, requestId, interfaceName, serviceName, regType, domain);
+    } else if (strcmp(cmd, "stop-resolve") == 0) {
+        stop(cli, argc, argv, "resolve");
+    } else if (strcmp(cmd, "start-service") == 0) {
+        if (mMonitor->startService()) {
+            cli->sendMsg(ResponseCode::CommandOkay, "Service Started", false);
+        } else {
+            cli->sendMsg(ResponseCode::ServiceStartFailed, "Service already running", false);
+        }
+    } else if (strcmp(cmd, "stop-service") == 0) {
+        if (mMonitor->stopService()) {
+            cli->sendMsg(ResponseCode::CommandOkay, "Service Stopped", false);
+        } else {
+            cli->sendMsg(ResponseCode::ServiceStopFailed, "Service still in use", false);
+        }
+    } else if (strcmp(cmd, "sethostname") == 0) {
+        if (argc != 4) {
+            cli->sendMsg(ResponseCode::CommandParameterError,
+                    "Invalid number of arguments to mdnssd sethostname", false);
+            return 0;
+        }
+        int requestId = atoi(argv[2]);
+        char *hostname = argv[3];
+        setHostname(cli, requestId, hostname);
+    } else if (strcmp(cmd, "stop-sethostname") == 0) {
+        stop(cli, argc, argv, "sethostname");
+    } else if (strcmp(cmd, "getaddrinfo") == 0) {
+        if (argc != 4) {
+            cli->sendMsg(ResponseCode::CommandParameterError,
+                    "Invalid number of arguments to mdnssd getaddrinfo", false);
+            return 0;
+        }
+        int requestId = atoi(argv[2]);
+        char *hostname = argv[3];
+        char *interfaceName = NULL;  // default
+        int protocol = 0;            // intelligient heuristic (both v4 + v6)
+        getAddrInfo(cli, requestId, interfaceName, protocol, hostname);
+    } else if (strcmp(cmd, "stop-getaddrinfo") == 0) {
+        stop(cli, argc, argv, "getaddrinfo");
+    } else {
+        if (VDBG) ALOGE("Unknown cmd %s", cmd);
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown mdnssd cmd", false);
+        return 0;
+    }
+    return 0;
+}
+
+MDnsSdListener::Monitor::Monitor() {
+    mHead = NULL;
+    mLiveCount = 0;
+    mPollFds = NULL;
+    mPollRefs = NULL;
+    mPollSize = 10;
+    socketpair(AF_LOCAL, SOCK_STREAM, 0, mCtrlSocketPair);
+    pthread_mutex_init(&mHeadMutex, NULL);
+
+    pthread_create(&mThread, NULL, MDnsSdListener::Monitor::threadStart, this);
+    pthread_detach(mThread);
+}
+
+void *MDnsSdListener::Monitor::threadStart(void *obj) {
+    Monitor *monitor = reinterpret_cast<Monitor *>(obj);
+
+    monitor->run();
+    delete monitor;
+    pthread_exit(NULL);
+    return NULL;
+}
+
+#define NAP_TIME 200  // 200 ms between polls
+static int wait_for_property(const char *name, const char *desired_value, int maxwait)
+{
+    char value[PROPERTY_VALUE_MAX] = {'\0'};
+    int maxnaps = (maxwait * 1000) / NAP_TIME;
+
+    if (maxnaps < 1) {
+        maxnaps = 1;
+    }
+
+    while (maxnaps-- > 0) {
+        usleep(NAP_TIME * 1000);
+        if (property_get(name, value, NULL)) {
+            if (desired_value == NULL || strcmp(value, desired_value) == 0) {
+                return 0;
+            }
+        }
+    }
+    return -1; /* failure */
+}
+
+int MDnsSdListener::Monitor::startService() {
+    int result = 0;
+    char property_value[PROPERTY_VALUE_MAX];
+    pthread_mutex_lock(&mHeadMutex);
+    property_get(MDNS_SERVICE_STATUS, property_value, "");
+    if (strcmp("running", property_value) != 0) {
+        ALOGD("Starting MDNSD");
+        property_set("ctl.start", MDNS_SERVICE_NAME);
+        wait_for_property(MDNS_SERVICE_STATUS, "running", 5);
+        result = -1;
+    } else {
+        result = 0;
+    }
+    pthread_mutex_unlock(&mHeadMutex);
+    return result;
+}
+
+int MDnsSdListener::Monitor::stopService() {
+    int result = 0;
+    pthread_mutex_lock(&mHeadMutex);
+    if (mHead == NULL) {
+        ALOGD("Stopping MDNSD");
+        property_set("ctl.stop", MDNS_SERVICE_NAME);
+        wait_for_property(MDNS_SERVICE_STATUS, "stopped", 5);
+        result = -1;
+    } else {
+        result = 0;
+    }
+    pthread_mutex_unlock(&mHeadMutex);
+    return result;
+}
+
+void MDnsSdListener::Monitor::run() {
+    int pollCount = 1;
+
+    mPollFds = (struct pollfd *)calloc(sizeof(struct pollfd), mPollSize);
+    mPollRefs = (DNSServiceRef **)calloc(sizeof(DNSServiceRef *), mPollSize);
+    LOG_ALWAYS_FATAL_IF((mPollFds == NULL), "initial calloc failed on mPollFds with a size of %d",
+            ((int)sizeof(struct pollfd)) * mPollSize);
+    LOG_ALWAYS_FATAL_IF((mPollRefs == NULL), "initial calloc failed on mPollRefs with a size of %d",
+            ((int)sizeof(DNSServiceRef *)) * mPollSize);
+
+    mPollFds[0].fd = mCtrlSocketPair[0];
+    mPollFds[0].events = POLLIN;
+
+    if (VDBG) ALOGD("MDnsSdListener starting to monitor");
+    while (1) {
+        if (VDBG) ALOGD("Going to poll with pollCount %d", pollCount);
+        int pollResults = poll(mPollFds, pollCount, 10000000);
+        if (pollResults < 0) {
+            ALOGE("Error in poll - got %d", errno);
+        } else if (pollResults > 0) {
+            if (VDBG) ALOGD("Monitor poll got data pollCount = %d, %d", pollCount, pollResults);
+            for(int i = 1; i < pollCount; i++) {
+                if (mPollFds[i].revents != 0) {
+                    if (VDBG) {
+                        ALOGD("Monitor found [%d].revents = %d - calling ProcessResults",
+                                i, mPollFds[i].revents);
+                    }
+                    DNSServiceProcessResult(*(mPollRefs[i]));
+                    mPollFds[i].revents = 0;
+                }
+            }
+            if (VDBG) ALOGD("controlSocket shows revent= %d", mPollFds[0].revents);
+            switch (mPollFds[0].revents) {
+                case POLLIN: {
+                    char readBuf[2];
+                    read(mCtrlSocketPair[0], &readBuf, 1);
+                    if (DBG) ALOGD("MDnsSdListener::Monitor got %c", readBuf[0]);
+                    if (memcmp(RESCAN, readBuf, 1) == 0) {
+                        pollCount = rescan();
+                    }
+                }
+            }
+            mPollFds[0].revents = 0;
+        } else {
+            if (VDBG) ALOGD("MDnsSdListener::Monitor poll timed out");
+        }
+    }
+    free(mPollFds);
+    free(mPollRefs);
+}
+
+#define DBG_RESCAN 0
+
+int MDnsSdListener::Monitor::rescan() {
+// rescan the list from mHead and make new pollfds and serviceRefs
+    if (VDBG) {
+        ALOGD("MDnsSdListener::Monitor poll rescanning - size=%d, live=%d", mPollSize, mLiveCount);
+    }
+    pthread_mutex_lock(&mHeadMutex);
+    Element **prevPtr = &mHead;
+    int i = 1;
+    if (mPollSize <= mLiveCount) {
+        mPollSize = mLiveCount + 5;
+        free(mPollFds);
+        free(mPollRefs);
+        mPollFds = (struct pollfd *)calloc(sizeof(struct pollfd), mPollSize);
+        mPollRefs = (DNSServiceRef **)calloc(sizeof(DNSServiceRef *), mPollSize);
+        LOG_ALWAYS_FATAL_IF((mPollFds == NULL), "calloc failed on mPollFds with a size of %d",
+                ((int)sizeof(struct pollfd)) * mPollSize);
+        LOG_ALWAYS_FATAL_IF((mPollRefs == NULL), "calloc failed on mPollRefs with a size of %d",
+                ((int)sizeof(DNSServiceRef *)) * mPollSize);
+    } else {
+        memset(mPollFds, 0, sizeof(struct pollfd) * mPollSize);
+        memset(mPollRefs, 0, sizeof(DNSServiceRef *) * mPollSize);
+    }
+    mPollFds[0].fd = mCtrlSocketPair[0];
+    mPollFds[0].events = POLLIN;
+    if (DBG_RESCAN) ALOGD("mHead = %p", mHead);
+    while (*prevPtr != NULL) {
+        if (DBG_RESCAN) ALOGD("checking %p, mReady = %d", *prevPtr, (*prevPtr)->mReady);
+        if ((*prevPtr)->mReady == 1) {
+            int fd = DNSServiceRefSockFD((*prevPtr)->mRef);
+            if (fd != -1) {
+                if (DBG_RESCAN) ALOGD("  adding FD %d", fd);
+                mPollFds[i].fd = fd;
+                mPollFds[i].events = POLLIN;
+                mPollRefs[i] = &((*prevPtr)->mRef);
+                i++;
+            } else {
+                ALOGE("Error retreving socket FD for live ServiceRef");
+            }
+            prevPtr = &((*prevPtr)->mNext); // advance to the next element
+        } else if ((*prevPtr)->mReady == -1) {
+            if (DBG_RESCAN) ALOGD("  removing %p from  play", *prevPtr);
+            Element *cur = *prevPtr;
+            *prevPtr = (cur)->mNext; // change our notion of this element and don't advance
+            delete cur;
+        } else if ((*prevPtr)->mReady == 0) {
+            // Not ready so just skip this node and continue on
+            if (DBG_RESCAN) ALOGD("%p not ready.  Continuing.", *prevPtr);
+            prevPtr = &((*prevPtr)->mNext);
+        }
+    }
+    pthread_mutex_unlock(&mHeadMutex);
+    return i;
+}
+
+DNSServiceRef *MDnsSdListener::Monitor::allocateServiceRef(int id, Context *context) {
+    if (lookupServiceRef(id) != NULL) {
+        delete(context);
+        return NULL;
+    }
+    Element *e = new Element(id, context);
+    pthread_mutex_lock(&mHeadMutex);
+    e->mNext = mHead;
+    mHead = e;
+    pthread_mutex_unlock(&mHeadMutex);
+    return &(e->mRef);
+}
+
+DNSServiceRef *MDnsSdListener::Monitor::lookupServiceRef(int id) {
+    pthread_mutex_lock(&mHeadMutex);
+    Element *cur = mHead;
+    while (cur != NULL) {
+        if (cur->mId == id) {
+            DNSServiceRef *result = &(cur->mRef);
+            pthread_mutex_unlock(&mHeadMutex);
+            return result;
+        }
+        cur = cur->mNext;
+    }
+    pthread_mutex_unlock(&mHeadMutex);
+    return NULL;
+}
+
+void MDnsSdListener::Monitor::startMonitoring(int id) {
+    if (VDBG) ALOGD("startMonitoring %d", id);
+    pthread_mutex_lock(&mHeadMutex);
+    Element *cur = mHead;
+    while (cur != NULL) {
+        if (cur->mId == id) {
+            if (DBG_RESCAN) ALOGD("marking %p as ready to be added", cur);
+            mLiveCount++;
+            cur->mReady = 1;
+            pthread_mutex_unlock(&mHeadMutex);
+            write(mCtrlSocketPair[1], RESCAN, 1);  // trigger a rescan for a fresh poll
+            if (VDBG) ALOGD("triggering rescan");
+            return;
+        }
+        cur = cur->mNext;
+    }
+    pthread_mutex_unlock(&mHeadMutex);
+}
+
+void MDnsSdListener::Monitor::freeServiceRef(int id) {
+    if (VDBG) ALOGD("freeServiceRef %d", id);
+    pthread_mutex_lock(&mHeadMutex);
+    Element **prevPtr = &mHead;
+    Element *cur;
+    while (*prevPtr != NULL) {
+        cur = *prevPtr;
+        if (cur->mId == id) {
+            if (DBG_RESCAN) ALOGD("marking %p as ready to be removed", cur);
+            mLiveCount--;
+            if (cur->mReady == 1) {
+                cur->mReady = -1; // tell poll thread to delete
+                write(mCtrlSocketPair[1], RESCAN, 1); // trigger a rescan for a fresh poll
+                if (VDBG) ALOGD("triggering rescan");
+            } else {
+                *prevPtr = cur->mNext;
+                delete cur;
+            }
+            pthread_mutex_unlock(&mHeadMutex);
+            return;
+        }
+        prevPtr = &(cur->mNext);
+    }
+    pthread_mutex_unlock(&mHeadMutex);
+}
diff --git a/netd/server/MDnsSdListener.h b/netd/server/MDnsSdListener.h
new file mode 100644
index 0000000..e9c6066
--- /dev/null
+++ b/netd/server/MDnsSdListener.h
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+#ifndef _MDNSSDLISTENER_H__
+#define _MDNSSDLISTENER_H__
+
+#include <pthread.h>
+#include <sysutils/FrameworkListener.h>
+#include <dns_sd.h>
+
+#include "NetdCommand.h"
+
+// callbacks
+void MDnsSdListenerDiscoverCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
+        uint32_t interfaceIndex, DNSServiceErrorType errorCode,
+        const char *serviceName, const char *regType, const char *replyDomain,
+        void *inContext);
+
+void MDnsSdListenerRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
+        DNSServiceErrorType errorCode, const char *serviceName, const char *regType,
+        const char *domain, void *inContext);
+
+void MDnsSdListenerResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interface,
+        DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port,
+        uint16_t txtLen, const unsigned char *txtRecord, void *inContext);
+
+void MDnsSdListenerSetHostnameCallback(DNSServiceRef, DNSServiceFlags flags,
+        DNSServiceErrorType errorCode, const char *hostname, void *inContext);
+
+void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
+        uint32_t interface, DNSServiceErrorType errorCode, const char *hostname,
+        const struct sockaddr *const sa, uint32_t ttl, void *inContext);
+
+#define RESCAN "1"
+
+class MDnsSdListener : public FrameworkListener {
+public:
+    MDnsSdListener();
+    virtual ~MDnsSdListener() {}
+
+    class Context {
+    public:
+        MDnsSdListener *mListener;
+        int mRefNumber;
+
+        Context(int refNumber, MDnsSdListener *m) {
+            mRefNumber = refNumber;
+            mListener = m;
+        }
+
+        ~Context() {
+        }
+    };
+
+    class Monitor {
+    public:
+        Monitor();
+        virtual ~Monitor() {}
+        DNSServiceRef *allocateServiceRef(int id, Context *c);
+        void startMonitoring(int id);
+        DNSServiceRef *lookupServiceRef(int id);
+        void freeServiceRef(int id);
+        static void *threadStart(void *handler);
+        int startService();
+        int stopService();
+    private:
+        void run();
+        int rescan(); // returns the number of elements in the poll
+        class Element {
+        public:
+            int mId;
+            Element *mNext;
+            DNSServiceRef mRef;
+            Context *mContext;
+            int mReady;
+            Element(int id, Context *context)
+                    : mId(id), mNext(NULL), mContext(context), mReady(0) {}
+            virtual ~Element() { delete(mContext); }
+        };
+        Element *mHead;
+        int mLiveCount;
+        struct pollfd *mPollFds;
+        DNSServiceRef **mPollRefs;
+        int mPollSize;
+        pthread_t mThread;
+        int mCtrlSocketPair[2];
+        pthread_mutex_t mHeadMutex;
+    };
+
+    class Handler : public NetdCommand {
+    public:
+        Handler(Monitor *m, MDnsSdListener *listener);
+        virtual ~Handler();
+        int runCommand(SocketClient *c, int argc, char** argv);
+
+        MDnsSdListener *mListener; // needed for broadcast purposes
+    private:
+        void stop(SocketClient *cli, int argc, char **argv, const char *str);
+
+        void discover(SocketClient *cli, const char *iface, const char *regType,
+                const char *domain, const int requestNumber,
+                const int requestFlags);
+
+        void serviceRegister(SocketClient *cli, int requestId, const char *interfaceName,
+                const char *serviceName, const char *serviceType, const char *domain,
+                const char *host, int port, int textLen, void *txtRecord);
+
+        void resolveService(SocketClient *cli, int requestId,
+                const char *interfaceName, const char *serviceName, const char *regType,
+                const char *domain);
+
+        void setHostname(SocketClient *cli, int requestId, const char *hostname);
+
+        void getAddrInfo(SocketClient *cli, int requestId, const char *interfaceName,
+                uint32_t protocol, const char *hostname);
+
+        int ifaceNameToI(const char *iface);
+        const char *iToIfaceName(int i);
+        DNSServiceFlags iToFlags(int i);
+        int flagsToI(DNSServiceFlags flags);
+        Monitor *mMonitor;
+    };
+};
+
+#endif
diff --git a/netd/server/NatController.cpp b/netd/server/NatController.cpp
new file mode 100644
index 0000000..19d19c7
--- /dev/null
+++ b/netd/server/NatController.cpp
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#define LOG_NDEBUG 0
+
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <cutils/properties.h>
+
+#define LOG_TAG "NatController"
+#include <cutils/log.h>
+#include <logwrap/logwrap.h>
+
+#include "NatController.h"
+#include "NetdConstants.h"
+#include "RouteController.h"
+
+const char* NatController::LOCAL_FORWARD = "natctrl_FORWARD";
+const char* NatController::LOCAL_MANGLE_FORWARD = "natctrl_mangle_FORWARD";
+const char* NatController::LOCAL_NAT_POSTROUTING = "natctrl_nat_POSTROUTING";
+const char* NatController::LOCAL_TETHER_COUNTERS_CHAIN = "natctrl_tether_counters";
+
+NatController::NatController() {
+}
+
+NatController::~NatController() {
+}
+
+struct CommandsAndArgs {
+    /* The array size doesn't really matter as the compiler will barf if too many initializers are specified. */
+    const char *cmd[32];
+    bool checkRes;
+};
+
+int NatController::runCmd(int argc, const char **argv) {
+    int res;
+
+    res = android_fork_execvp(argc, (char **)argv, NULL, false, false);
+
+#if !LOG_NDEBUG
+    std::string full_cmd = argv[0];
+    argc--; argv++;
+    /*
+     * HACK: Sometimes runCmd() is called with a ridcously large value (32)
+     * and it works because the argv[] contains a NULL after the last
+     * true argv. So here we use the NULL argv[] to terminate when the argc
+     * is horribly wrong, and argc for the normal cases.
+     */
+    for (; argc && argv[0]; argc--, argv++) {
+        full_cmd += " ";
+        full_cmd += argv[0];
+    }
+    ALOGV("runCmd(%s) res=%d", full_cmd.c_str(), res);
+#endif
+    return res;
+}
+
+int NatController::setupIptablesHooks() {
+    int res;
+    res = setDefaults();
+    if (res < 0) {
+        return res;
+    }
+
+    struct CommandsAndArgs defaultCommands[] = {
+        /*
+         * First chain is for tethering counters.
+         * This chain is reached via --goto, and then RETURNS.
+         *
+         * Second chain is used to limit downstream mss to the upstream pmtu
+         * so we don't end up fragmenting every large packet tethered devices
+         * send.  Note this feature requires kernel support with flag
+         * CONFIG_NETFILTER_XT_TARGET_TCPMSS=y, which not all builds will have,
+         * so the final rule is allowed to fail.
+         * Bug 17629786 asks to make the failure more obvious, or even fatal
+         * so that all builds eventually gain the performance improvement.
+         */
+        {{IPTABLES_PATH, "-w", "-F", LOCAL_TETHER_COUNTERS_CHAIN,}, 0},
+        {{IPTABLES_PATH, "-w", "-X", LOCAL_TETHER_COUNTERS_CHAIN,}, 0},
+        {{IPTABLES_PATH, "-w", "-N", LOCAL_TETHER_COUNTERS_CHAIN,}, 1},
+        {{IPTABLES_PATH, "-w", "-t", "mangle", "-A", LOCAL_MANGLE_FORWARD, "-p", "tcp", "--tcp-flags",
+                "SYN", "SYN", "-j", "TCPMSS", "--clamp-mss-to-pmtu"}, 0},
+    };
+    for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) {
+        if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) &&
+            defaultCommands[cmdNum].checkRes) {
+                return -1;
+        }
+    }
+    ifacePairList.clear();
+
+    return 0;
+}
+
+int NatController::setDefaults() {
+    /*
+     * The following only works because:
+     *  - the defaultsCommands[].cmd array is padded with NULL, and
+     *  - the 1st argc of runCmd() will just be the max for the CommandsAndArgs[].cmd, and
+     *  - internally it will be memcopied to an array and terminated with a NULL.
+     */
+    struct CommandsAndArgs defaultCommands[] = {
+        {{IPTABLES_PATH, "-w", "-F", LOCAL_FORWARD,}, 1},
+        {{IPTABLES_PATH, "-w", "-A", LOCAL_FORWARD, "-j", "DROP"}, 1},
+        {{IPTABLES_PATH, "-w", "-t", "nat", "-F", LOCAL_NAT_POSTROUTING}, 1},
+    };
+    for (unsigned int cmdNum = 0; cmdNum < ARRAY_SIZE(defaultCommands); cmdNum++) {
+        if (runCmd(ARRAY_SIZE(defaultCommands[cmdNum].cmd), defaultCommands[cmdNum].cmd) &&
+            defaultCommands[cmdNum].checkRes) {
+                return -1;
+        }
+    }
+
+    natCount = 0;
+
+    return 0;
+}
+
+int NatController::enableNat(const char* intIface, const char* extIface) {
+    ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface);
+
+    if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
+        errno = ENODEV;
+        return -1;
+    }
+
+    /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */
+    if (!strcmp(intIface, extIface)) {
+        ALOGE("Duplicate interface specified: %s %s", intIface, extIface);
+        errno = EINVAL;
+        return -1;
+    }
+
+    // add this if we are the first added nat
+    if (natCount == 0) {
+        const char *cmd[] = {
+                IPTABLES_PATH,
+                "-w",
+                "-t",
+                "nat",
+                "-A",
+                LOCAL_NAT_POSTROUTING,
+                "-o",
+                extIface,
+                "-j",
+                "MASQUERADE"
+        };
+        if (runCmd(ARRAY_SIZE(cmd), cmd)) {
+            ALOGE("Error setting postroute rule: iface=%s", extIface);
+            // unwind what's been done, but don't care about success - what more could we do?
+            setDefaults();
+            return -1;
+        }
+    }
+
+    if (setForwardRules(true, intIface, extIface) != 0) {
+        ALOGE("Error setting forward rules");
+        if (natCount == 0) {
+            setDefaults();
+        }
+        errno = ENODEV;
+        return -1;
+    }
+
+    /* Always make sure the drop rule is at the end */
+    const char *cmd1[] = {
+            IPTABLES_PATH,
+            "-w",
+            "-D",
+            LOCAL_FORWARD,
+            "-j",
+            "DROP"
+    };
+    runCmd(ARRAY_SIZE(cmd1), cmd1);
+    const char *cmd2[] = {
+            IPTABLES_PATH,
+            "-w",
+            "-A",
+            LOCAL_FORWARD,
+            "-j",
+            "DROP"
+    };
+    runCmd(ARRAY_SIZE(cmd2), cmd2);
+
+    natCount++;
+    return 0;
+}
+
+bool NatController::checkTetherCountingRuleExist(const char *pair_name) {
+    std::list<std::string>::iterator it;
+
+    for (it = ifacePairList.begin(); it != ifacePairList.end(); it++) {
+        if (*it == pair_name) {
+            /* We already have this counter */
+            return true;
+        }
+    }
+    return false;
+}
+
+int NatController::setTetherCountingRules(bool add, const char *intIface, const char *extIface) {
+
+    /* We only ever add tethering quota rules so that they stick. */
+    if (!add) {
+        return 0;
+    }
+    char *pair_name;
+    asprintf(&pair_name, "%s_%s", intIface, extIface);
+
+    if (checkTetherCountingRuleExist(pair_name)) {
+        free(pair_name);
+        return 0;
+    }
+    const char *cmd2b[] = {
+            IPTABLES_PATH,
+            "-w",
+            "-A",
+            LOCAL_TETHER_COUNTERS_CHAIN,
+            "-i",
+            intIface,
+            "-o",
+            extIface,
+            "-j",
+          "RETURN"
+    };
+
+    if (runCmd(ARRAY_SIZE(cmd2b), cmd2b) && add) {
+        free(pair_name);
+        return -1;
+    }
+    ifacePairList.push_front(pair_name);
+    free(pair_name);
+
+    asprintf(&pair_name, "%s_%s", extIface, intIface);
+    if (checkTetherCountingRuleExist(pair_name)) {
+        free(pair_name);
+        return 0;
+    }
+
+    const char *cmd3b[] = {
+            IPTABLES_PATH,
+            "-w",
+            "-A",
+            LOCAL_TETHER_COUNTERS_CHAIN,
+            "-i",
+            extIface,
+            "-o",
+            intIface,
+            "-j",
+            "RETURN"
+    };
+
+    if (runCmd(ARRAY_SIZE(cmd3b), cmd3b) && add) {
+        // unwind what's been done, but don't care about success - what more could we do?
+        free(pair_name);
+        return -1;
+    }
+    ifacePairList.push_front(pair_name);
+    free(pair_name);
+    return 0;
+}
+
+int NatController::setForwardRules(bool add, const char *intIface, const char *extIface) {
+    const char *cmd1[] = {
+            IPTABLES_PATH,
+            "-w",
+            add ? "-A" : "-D",
+            LOCAL_FORWARD,
+            "-i",
+            extIface,
+            "-o",
+            intIface,
+            "-m",
+            "state",
+            "--state",
+            "ESTABLISHED,RELATED",
+            "-g",
+            LOCAL_TETHER_COUNTERS_CHAIN
+    };
+    int rc = 0;
+
+    if (runCmd(ARRAY_SIZE(cmd1), cmd1) && add) {
+        return -1;
+    }
+
+    const char *cmd2[] = {
+            IPTABLES_PATH,
+            "-w",
+            add ? "-A" : "-D",
+            LOCAL_FORWARD,
+            "-i",
+            intIface,
+            "-o",
+            extIface,
+            "-m",
+            "state",
+            "--state",
+            "INVALID",
+            "-j",
+            "DROP"
+    };
+
+    const char *cmd3[] = {
+            IPTABLES_PATH,
+            "-w",
+            add ? "-A" : "-D",
+            LOCAL_FORWARD,
+            "-i",
+            intIface,
+            "-o",
+            extIface,
+            "-g",
+            LOCAL_TETHER_COUNTERS_CHAIN
+    };
+
+    if (runCmd(ARRAY_SIZE(cmd2), cmd2) && add) {
+        // bail on error, but only if adding
+        rc = -1;
+        goto err_invalid_drop;
+    }
+
+    if (runCmd(ARRAY_SIZE(cmd3), cmd3) && add) {
+        // unwind what's been done, but don't care about success - what more could we do?
+        rc = -1;
+        goto err_return;
+    }
+
+    if (setTetherCountingRules(add, intIface, extIface) && add) {
+        rc = -1;
+        goto err_return;
+    }
+
+    return 0;
+
+err_return:
+    cmd2[2] = "-D";
+    runCmd(ARRAY_SIZE(cmd2), cmd2);
+err_invalid_drop:
+    cmd1[2] = "-D";
+    runCmd(ARRAY_SIZE(cmd1), cmd1);
+    return rc;
+}
+
+int NatController::disableNat(const char* intIface, const char* extIface) {
+    if (!isIfaceName(intIface) || !isIfaceName(extIface)) {
+        errno = ENODEV;
+        return -1;
+    }
+
+    setForwardRules(false, intIface, extIface);
+    if (--natCount <= 0) {
+        // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
+        setDefaults();
+    }
+    return 0;
+}
diff --git a/netd/server/NatController.h b/netd/server/NatController.h
new file mode 100644
index 0000000..f23bf84
--- /dev/null
+++ b/netd/server/NatController.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _NAT_CONTROLLER_H
+#define _NAT_CONTROLLER_H
+
+#include <linux/in.h>
+#include <list>
+#include <string>
+
+class NatController {
+public:
+    NatController();
+    virtual ~NatController();
+
+    int enableNat(const char* intIface, const char* extIface);
+    int disableNat(const char* intIface, const char* extIface);
+    int setupIptablesHooks();
+
+    static const char* LOCAL_FORWARD;
+    static const char* LOCAL_MANGLE_FORWARD;
+    static const char* LOCAL_NAT_POSTROUTING;
+    static const char* LOCAL_TETHER_COUNTERS_CHAIN;
+
+    // List of strings of interface pairs.
+    std::list<std::string> ifacePairList;
+
+private:
+    int natCount;
+
+    bool checkTetherCountingRuleExist(const char *pair_name);
+
+    int setDefaults();
+    int runCmd(int argc, const char **argv);
+    int setForwardRules(bool set, const char *intIface, const char *extIface);
+    int setTetherCountingRules(bool add, const char *intIface, const char *extIface);
+};
+
+#endif
diff --git a/netd/server/NetdCommand.cpp b/netd/server/NetdCommand.cpp
new file mode 100644
index 0000000..3bd9322
--- /dev/null
+++ b/netd/server/NetdCommand.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2008 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 "NetdCommand.h"
+
+NetdCommand::NetdCommand(const char *cmd) :
+              FrameworkCommand(cmd)  {
+}
diff --git a/netd/server/NetdCommand.h b/netd/server/NetdCommand.h
new file mode 100644
index 0000000..8e3e54b
--- /dev/null
+++ b/netd/server/NetdCommand.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _NETD_COMMAND_H
+#define _NETD_COMMAND_H
+
+#include <sysutils/FrameworkCommand.h>
+
+class NetdCommand : public FrameworkCommand {
+public:
+    explicit NetdCommand(const char *cmd);
+    virtual ~NetdCommand() {}
+};
+
+#endif
diff --git a/netd/server/NetdConstants.cpp b/netd/server/NetdConstants.cpp
new file mode 100644
index 0000000..c86538b
--- /dev/null
+++ b/netd/server/NetdConstants.cpp
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+
+#define LOG_TAG "Netd"
+
+#include <cutils/log.h>
+#include <logwrap/logwrap.h>
+
+#include "NetdConstants.h"
+
+const char * const OEM_SCRIPT_PATH = "/system/bin/oem-iptables-init.sh";
+const char * const IPTABLES_PATH = "/system/bin/iptables";
+const char * const IP6TABLES_PATH = "/system/bin/ip6tables";
+const char * const TC_PATH = "/system/bin/tc";
+const char * const IP_PATH = "/system/bin/ip";
+const char * const ADD = "add";
+const char * const DEL = "del";
+
+static void logExecError(const char* argv[], int res, int status) {
+    const char** argp = argv;
+    std::string args = "";
+    while (*argp) {
+        args += *argp;
+        args += ' ';
+        argp++;
+    }
+    ALOGE("exec() res=%d, status=%d for %s", res, status, args.c_str());
+}
+
+static int execIptablesCommand(int argc, const char *argv[], bool silent) {
+    int res;
+    int status;
+
+    res = android_fork_execvp(argc, (char **)argv, &status, false,
+        !silent);
+    if (res || !WIFEXITED(status) || WEXITSTATUS(status)) {
+        if (!silent) {
+            logExecError(argv, res, status);
+        }
+        if (res)
+            return res;
+        if (!WIFEXITED(status))
+            return ECHILD;
+    }
+    return WEXITSTATUS(status);
+}
+
+static int execIptables(IptablesTarget target, bool silent, va_list args) {
+    /* Read arguments from incoming va_list; we expect the list to be NULL terminated. */
+    std::list<const char*> argsList;
+    argsList.push_back(NULL);
+    const char* arg;
+
+    // Wait to avoid failure due to another process holding the lock
+    argsList.push_back("-w");
+
+    do {
+        arg = va_arg(args, const char *);
+        argsList.push_back(arg);
+    } while (arg);
+
+    int i = 0;
+    const char* argv[argsList.size()];
+    std::list<const char*>::iterator it;
+    for (it = argsList.begin(); it != argsList.end(); it++, i++) {
+        argv[i] = *it;
+    }
+
+    int res = 0;
+    if (target == V4 || target == V4V6) {
+        argv[0] = IPTABLES_PATH;
+        res |= execIptablesCommand(argsList.size(), argv, silent);
+    }
+    if (target == V6 || target == V4V6) {
+        argv[0] = IP6TABLES_PATH;
+        res |= execIptablesCommand(argsList.size(), argv, silent);
+    }
+    return res;
+}
+
+int execIptables(IptablesTarget target, ...) {
+    va_list args;
+    va_start(args, target);
+    int res = execIptables(target, false, args);
+    va_end(args);
+    return res;
+}
+
+int execIptablesSilently(IptablesTarget target, ...) {
+    va_list args;
+    va_start(args, target);
+    int res = execIptables(target, true, args);
+    va_end(args);
+    return res;
+}
+
+/*
+ * Check an interface name for plausibility. This should e.g. help against
+ * directory traversal.
+ */
+bool isIfaceName(const char *name) {
+    size_t i;
+    size_t name_len = strlen(name);
+    if ((name_len == 0) || (name_len > IFNAMSIZ)) {
+        return false;
+    }
+
+    /* First character must be alphanumeric */
+    if (!isalnum(name[0])) {
+        return false;
+    }
+
+    for (i = 1; i < name_len; i++) {
+        if (!isalnum(name[i]) && (name[i] != '_') && (name[i] != '-') && (name[i] != ':')) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+int parsePrefix(const char *prefix, uint8_t *family, void *address, int size, uint8_t *prefixlen) {
+    if (!prefix || !family || !address || !prefixlen) {
+        return -EFAULT;
+    }
+
+    // Find the '/' separating address from prefix length.
+    const char *slash = strchr(prefix, '/');
+    const char *prefixlenString = slash + 1;
+    if (!slash || !*prefixlenString)
+        return -EINVAL;
+
+    // Convert the prefix length to a uint8_t.
+    char *endptr;
+    unsigned templen;
+    templen = strtoul(prefixlenString, &endptr, 10);
+    if (*endptr || templen > 255) {
+        return -EINVAL;
+    }
+    *prefixlen = templen;
+
+    // Copy the address part of the prefix to a local buffer. We have to copy
+    // because inet_pton and getaddrinfo operate on null-terminated address
+    // strings, but prefix is const and has '/' after the address.
+    std::string addressString(prefix, slash - prefix);
+
+    // Parse the address.
+    addrinfo *res;
+    addrinfo hints = {
+        .ai_flags = AI_NUMERICHOST,
+    };
+    int ret = getaddrinfo(addressString.c_str(), NULL, &hints, &res);
+    if (ret || !res) {
+        return -EINVAL;  // getaddrinfo return values are not errno values.
+    }
+
+    // Convert the address string to raw address bytes.
+    void *rawAddress;
+    int rawLength;
+    switch (res[0].ai_family) {
+        case AF_INET: {
+            if (*prefixlen > 32) {
+                return -EINVAL;
+            }
+            sockaddr_in *sin = (sockaddr_in *) res[0].ai_addr;
+            rawAddress = &sin->sin_addr;
+            rawLength = 4;
+            break;
+        }
+        case AF_INET6: {
+            if (*prefixlen > 128) {
+                return -EINVAL;
+            }
+            sockaddr_in6 *sin6 = (sockaddr_in6 *) res[0].ai_addr;
+            rawAddress = &sin6->sin6_addr;
+            rawLength = 16;
+            break;
+        }
+        default: {
+            freeaddrinfo(res);
+            return -EAFNOSUPPORT;
+        }
+    }
+
+    if (rawLength > size) {
+        freeaddrinfo(res);
+        return -ENOSPC;
+    }
+
+    *family = res[0].ai_family;
+    memcpy(address, rawAddress, rawLength);
+    freeaddrinfo(res);
+
+    return rawLength;
+}
diff --git a/netd/server/NetdConstants.h b/netd/server/NetdConstants.h
new file mode 100644
index 0000000..296661d
--- /dev/null
+++ b/netd/server/NetdConstants.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#ifndef _NETD_CONSTANTS_H
+#define _NETD_CONSTANTS_H
+
+#include <string>
+#include <list>
+#include <stdarg.h>
+
+const int PROTECT_MARK = 0x1;
+
+extern const char * const IPTABLES_PATH;
+extern const char * const IP6TABLES_PATH;
+extern const char * const IP_PATH;
+extern const char * const TC_PATH;
+extern const char * const OEM_SCRIPT_PATH;
+extern const char * const ADD;
+extern const char * const DEL;
+
+enum IptablesTarget { V4, V6, V4V6 };
+
+int execIptables(IptablesTarget target, ...);
+int execIptablesSilently(IptablesTarget target, ...);
+bool isIfaceName(const char *name);
+int parsePrefix(const char *prefix, uint8_t *family, void *address, int size, uint8_t *prefixlen);
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+
+#define __INT_STRLEN(i) sizeof(#i)
+#define _INT_STRLEN(i) __INT_STRLEN(i)
+#define UINT32_STRLEN _INT_STRLEN(UINT32_MAX)
+#define UINT32_HEX_STRLEN sizeof("0x12345678")
+
+#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
+
+const uid_t INVALID_UID = static_cast<uid_t>(-1);
+
+#endif
diff --git a/netd/server/NetlinkHandler.cpp b/netd/server/NetlinkHandler.cpp
new file mode 100644
index 0000000..718fbdb
--- /dev/null
+++ b/netd/server/NetlinkHandler.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2008 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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define LOG_TAG "Netd"
+
+#include <cutils/log.h>
+
+#include <netutils/ifc.h>
+#include <sysutils/NetlinkEvent.h>
+#include "NetlinkHandler.h"
+#include "NetlinkManager.h"
+#include "ResponseCode.h"
+#include "SockDiag.h"
+
+static const char *kUpdated = "updated";
+static const char *kRemoved = "removed";
+
+NetlinkHandler::NetlinkHandler(NetlinkManager *nm, int listenerSocket,
+                               int format) :
+                        NetlinkListener(listenerSocket, format) {
+    mNm = nm;
+}
+
+NetlinkHandler::~NetlinkHandler() {
+}
+
+int NetlinkHandler::start() {
+    return this->startListener();
+}
+
+int NetlinkHandler::stop() {
+    return this->stopListener();
+}
+
+void NetlinkHandler::onEvent(NetlinkEvent *evt) {
+    const char *subsys = evt->getSubsystem();
+    if (!subsys) {
+        ALOGW("No subsystem found in netlink event");
+        return;
+    }
+
+    if (!strcmp(subsys, "net")) {
+        NetlinkEvent::Action action = evt->getAction();
+        const char *iface = evt->findParam("INTERFACE");
+
+        if (action == NetlinkEvent::Action::kAdd) {
+            notifyInterfaceAdded(iface);
+        } else if (action == NetlinkEvent::Action::kRemove) {
+            notifyInterfaceRemoved(iface);
+        } else if (action == NetlinkEvent::Action::kChange) {
+            evt->dump();
+            notifyInterfaceChanged("nana", true);
+        } else if (action == NetlinkEvent::Action::kLinkUp) {
+            notifyInterfaceLinkChanged(iface, true);
+        } else if (action == NetlinkEvent::Action::kLinkDown) {
+            notifyInterfaceLinkChanged(iface, false);
+        } else if (action == NetlinkEvent::Action::kAddressUpdated ||
+                   action == NetlinkEvent::Action::kAddressRemoved) {
+            const char *address = evt->findParam("ADDRESS");
+            const char *flags = evt->findParam("FLAGS");
+            const char *scope = evt->findParam("SCOPE");
+            if (action == NetlinkEvent::Action::kAddressRemoved && iface && address) {
+                // Note: if this interface was deleted, iface is "" and we don't notify.
+                SockDiag sd;
+                if (sd.open()) {
+                    char addrstr[INET6_ADDRSTRLEN];
+                    strncpy(addrstr, address, sizeof(addrstr));
+                    char *slash = strchr(addrstr, '/');
+                    if (slash) {
+                        *slash = '\0';
+                    }
+
+                    int ret = sd.destroySockets(addrstr);
+                    if (ret < 0) {
+                        ALOGE("Error destroying sockets: %s", strerror(ret));
+                    }
+                } else {
+                    ALOGE("Error opening NETLINK_SOCK_DIAG socket: %s", strerror(errno));
+                }
+
+                // TODO: delete this once SOCK_DESTROY works everywhere.
+                if (iface[0]) {
+                    int resetMask = strchr(address, ':') ?
+                            RESET_IPV6_ADDRESSES : RESET_IPV4_ADDRESSES;
+                    resetMask |= RESET_IGNORE_INTERFACE_ADDRESS;
+                    if (int ret = ifc_reset_connections(iface, resetMask)) {
+                        ALOGE("ifc_reset_connections failed on iface %s for address %s (%s)", iface,
+                              address, strerror(ret));
+                    }
+                }
+            }
+            if (iface && iface[0] && address && flags && scope) {
+                notifyAddressChanged(action, address, iface, flags, scope);
+            }
+        } else if (action == NetlinkEvent::Action::kRdnss) {
+            const char *lifetime = evt->findParam("LIFETIME");
+            const char *servers = evt->findParam("SERVERS");
+            if (lifetime && servers) {
+                notifyInterfaceDnsServers(iface, lifetime, servers);
+            }
+        } else if (action == NetlinkEvent::Action::kRouteUpdated ||
+                   action == NetlinkEvent::Action::kRouteRemoved) {
+            const char *route = evt->findParam("ROUTE");
+            const char *gateway = evt->findParam("GATEWAY");
+            const char *iface = evt->findParam("INTERFACE");
+            if (route && (gateway || iface)) {
+                notifyRouteChange(action, route, gateway, iface);
+            }
+        }
+
+    } else if (!strcmp(subsys, "qlog")) {
+        const char *alertName = evt->findParam("ALERT_NAME");
+        const char *iface = evt->findParam("INTERFACE");
+        notifyQuotaLimitReached(alertName, iface);
+
+    } else if (!strcmp(subsys, "strict")) {
+        const char *uid = evt->findParam("UID");
+        const char *hex = evt->findParam("HEX");
+        notifyStrictCleartext(uid, hex);
+
+    } else if (!strcmp(subsys, "xt_idletimer")) {
+        const char *label = evt->findParam("INTERFACE");
+        const char *state = evt->findParam("STATE");
+        const char *timestamp = evt->findParam("TIME_NS");
+        const char *uid = evt->findParam("UID");
+        if (state)
+            notifyInterfaceClassActivity(label, !strcmp("active", state),
+                                         timestamp, uid);
+
+#if !LOG_NDEBUG
+    } else if (strcmp(subsys, "platform") && strcmp(subsys, "backlight")) {
+        /* It is not a VSYNC or a backlight event */
+        ALOGV("unexpected event from subsystem %s", subsys);
+#endif
+    }
+}
+
+void NetlinkHandler::notify(int code, const char *format, ...) {
+    char *msg;
+    va_list args;
+    va_start(args, format);
+    if (vasprintf(&msg, format, args) >= 0) {
+        mNm->getBroadcaster()->sendBroadcast(code, msg, false);
+        free(msg);
+    } else {
+        SLOGE("Failed to send notification: vasprintf: %s", strerror(errno));
+    }
+    va_end(args);
+}
+
+void NetlinkHandler::notifyInterfaceAdded(const char *name) {
+    notify(ResponseCode::InterfaceChange, "Iface added %s", name);
+}
+
+void NetlinkHandler::notifyInterfaceRemoved(const char *name) {
+    notify(ResponseCode::InterfaceChange, "Iface removed %s", name);
+}
+
+void NetlinkHandler::notifyInterfaceChanged(const char *name, bool isUp) {
+    notify(ResponseCode::InterfaceChange,
+           "Iface changed %s %s", name, (isUp ? "up" : "down"));
+}
+
+void NetlinkHandler::notifyInterfaceLinkChanged(const char *name, bool isUp) {
+    notify(ResponseCode::InterfaceChange,
+           "Iface linkstate %s %s", name, (isUp ? "up" : "down"));
+}
+
+void NetlinkHandler::notifyQuotaLimitReached(const char *name, const char *iface) {
+    notify(ResponseCode::BandwidthControl, "limit alert %s %s", name, iface);
+}
+
+void NetlinkHandler::notifyInterfaceClassActivity(const char *name,
+                                                  bool isActive,
+                                                  const char *timestamp,
+                                                  const char *uid) {
+    if (timestamp == NULL)
+        notify(ResponseCode::InterfaceClassActivity,
+           "IfaceClass %s %s", isActive ? "active" : "idle", name);
+    else if (uid != NULL && isActive)
+        notify(ResponseCode::InterfaceClassActivity,
+           "IfaceClass active %s %s %s", name, timestamp, uid);
+    else
+        notify(ResponseCode::InterfaceClassActivity,
+           "IfaceClass %s %s %s", isActive ? "active" : "idle", name, timestamp);
+}
+
+void NetlinkHandler::notifyAddressChanged(NetlinkEvent::Action action, const char *addr,
+                                          const char *iface, const char *flags,
+                                          const char *scope) {
+    notify(ResponseCode::InterfaceAddressChange,
+           "Address %s %s %s %s %s",
+           (action == NetlinkEvent::Action::kAddressUpdated) ? kUpdated : kRemoved,
+           addr, iface, flags, scope);
+}
+
+void NetlinkHandler::notifyInterfaceDnsServers(const char *iface,
+                                               const char *lifetime,
+                                               const char *servers) {
+    notify(ResponseCode::InterfaceDnsInfo, "DnsInfo servers %s %s %s",
+           iface, lifetime, servers);
+}
+
+void NetlinkHandler::notifyRouteChange(NetlinkEvent::Action action, const char *route,
+                                       const char *gateway, const char *iface) {
+    notify(ResponseCode::RouteChange,
+           "Route %s %s%s%s%s%s",
+           (action == NetlinkEvent::Action::kRouteUpdated) ? kUpdated : kRemoved,
+           route,
+           *gateway ? " via " : "",
+           gateway,
+           *iface ? " dev " : "",
+           iface);
+}
+
+void NetlinkHandler::notifyStrictCleartext(const char* uid, const char* hex) {
+    notify(ResponseCode::StrictCleartext, "%s %s", uid, hex);
+}
diff --git a/netd/server/NetlinkHandler.h b/netd/server/NetlinkHandler.h
new file mode 100644
index 0000000..d97c864
--- /dev/null
+++ b/netd/server/NetlinkHandler.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _NETLINKHANDLER_H
+#define _NETLINKHANDLER_H
+
+#include <sysutils/NetlinkEvent.h>
+#include <sysutils/NetlinkListener.h>
+#include "NetlinkManager.h"
+
+class NetlinkHandler: public NetlinkListener {
+    NetlinkManager *mNm;
+
+public:
+    NetlinkHandler(NetlinkManager *nm, int listenerSocket, int format);
+    virtual ~NetlinkHandler();
+
+    int start(void);
+    int stop(void);
+
+protected:
+    virtual void onEvent(NetlinkEvent *evt);
+
+    void notify(int code, const char *format, ...);
+    void notifyInterfaceAdded(const char *name);
+    void notifyInterfaceRemoved(const char *name);
+    void notifyInterfaceChanged(const char *name, bool isUp);
+    void notifyInterfaceLinkChanged(const char *name, bool isUp);
+    void notifyQuotaLimitReached(const char *name, const char *iface);
+    void notifyInterfaceClassActivity(const char *name, bool isActive,
+                                      const char *timestamp, const char *uid);
+    void notifyAddressChanged(NetlinkEvent::Action action, const char *addr, const char *iface,
+                              const char *flags, const char *scope);
+    void notifyInterfaceDnsServers(const char *iface, const char *lifetime,
+                                   const char *servers);
+    void notifyRouteChange(NetlinkEvent::Action action, const char *route, const char *gateway, const char *iface);
+    void notifyStrictCleartext(const char* uid, const char* hex);
+};
+#endif
diff --git a/netd/server/NetlinkManager.cpp b/netd/server/NetlinkManager.cpp
new file mode 100644
index 0000000..76af46f
--- /dev/null
+++ b/netd/server/NetlinkManager.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2008 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 <stdio.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#define LOG_TAG "Netd"
+
+#include <cutils/log.h>
+
+#include <netlink/attr.h>
+#include <netlink/genl/genl.h>
+#include <netlink/handlers.h>
+#include <netlink/msg.h>
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_log.h>
+#include <linux/netfilter/nfnetlink_compat.h>
+
+#include <arpa/inet.h>
+
+#include "NetlinkManager.h"
+#include "NetlinkHandler.h"
+
+#include "pcap-netfilter-linux-android.h"
+
+const int NetlinkManager::NFLOG_QUOTA_GROUP = 1;
+const int NetlinkManager::NETFILTER_STRICT_GROUP = 2;
+
+NetlinkManager *NetlinkManager::sInstance = NULL;
+
+NetlinkManager *NetlinkManager::Instance() {
+    if (!sInstance)
+        sInstance = new NetlinkManager();
+    return sInstance;
+}
+
+NetlinkManager::NetlinkManager() {
+    mBroadcaster = NULL;
+}
+
+NetlinkManager::~NetlinkManager() {
+}
+
+NetlinkHandler *NetlinkManager::setupSocket(int *sock, int netlinkFamily,
+    int groups, int format, bool configNflog) {
+
+    struct sockaddr_nl nladdr;
+    int sz = 64 * 1024;
+    int on = 1;
+
+    memset(&nladdr, 0, sizeof(nladdr));
+    nladdr.nl_family = AF_NETLINK;
+    nladdr.nl_pid = getpid();
+    nladdr.nl_groups = groups;
+
+    if ((*sock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, netlinkFamily)) < 0) {
+        ALOGE("Unable to create netlink socket: %s", strerror(errno));
+        return NULL;
+    }
+
+    if (setsockopt(*sock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {
+        ALOGE("Unable to set uevent socket SO_RCVBUFFORCE option: %s", strerror(errno));
+        close(*sock);
+        return NULL;
+    }
+
+    if (setsockopt(*sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
+        SLOGE("Unable to set uevent socket SO_PASSCRED option: %s", strerror(errno));
+        close(*sock);
+        return NULL;
+    }
+
+    if (bind(*sock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
+        ALOGE("Unable to bind netlink socket: %s", strerror(errno));
+        close(*sock);
+        return NULL;
+    }
+
+    if (configNflog) {
+        if (android_nflog_send_config_cmd(*sock, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
+            ALOGE("Failed NFULNL_CFG_CMD_PF_UNBIND: %s", strerror(errno));
+            return NULL;
+        }
+        if (android_nflog_send_config_cmd(*sock, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
+            ALOGE("Failed NFULNL_CFG_CMD_PF_BIND: %s", strerror(errno));
+            return NULL;
+        }
+        if (android_nflog_send_config_cmd(*sock, 0, NFULNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
+            ALOGE("Failed NFULNL_CFG_CMD_BIND: %s", strerror(errno));
+            return NULL;
+        }
+    }
+
+    NetlinkHandler *handler = new NetlinkHandler(this, *sock, format);
+    if (handler->start()) {
+        ALOGE("Unable to start NetlinkHandler: %s", strerror(errno));
+        close(*sock);
+        return NULL;
+    }
+
+    return handler;
+}
+
+int NetlinkManager::start() {
+    if ((mUeventHandler = setupSocket(&mUeventSock, NETLINK_KOBJECT_UEVENT,
+         0xffffffff, NetlinkListener::NETLINK_FORMAT_ASCII, false)) == NULL) {
+        return -1;
+    }
+
+    if ((mRouteHandler = setupSocket(&mRouteSock, NETLINK_ROUTE,
+                                     RTMGRP_LINK |
+                                     RTMGRP_IPV4_IFADDR |
+                                     RTMGRP_IPV6_IFADDR |
+                                     RTMGRP_IPV6_ROUTE |
+                                     (1 << (RTNLGRP_ND_USEROPT - 1)),
+         NetlinkListener::NETLINK_FORMAT_BINARY, false)) == NULL) {
+        return -1;
+    }
+
+    if ((mQuotaHandler = setupSocket(&mQuotaSock, NETLINK_NFLOG,
+            NFLOG_QUOTA_GROUP, NetlinkListener::NETLINK_FORMAT_BINARY, false)) == NULL) {
+        ALOGE("Unable to open quota socket");
+        // TODO: return -1 once the emulator gets a new kernel.
+    }
+
+    if ((mStrictHandler = setupSocket(&mStrictSock, NETLINK_NETFILTER,
+            0, NetlinkListener::NETLINK_FORMAT_BINARY_UNICAST, true)) == NULL) {
+        ALOGE("Unable to open strict socket");
+        // TODO: return -1 once the emulator gets a new kernel.
+    }
+
+    return 0;
+}
+
+int NetlinkManager::stop() {
+    int status = 0;
+
+    if (mUeventHandler->stop()) {
+        ALOGE("Unable to stop uevent NetlinkHandler: %s", strerror(errno));
+        status = -1;
+    }
+
+    delete mUeventHandler;
+    mUeventHandler = NULL;
+
+    close(mUeventSock);
+    mUeventSock = -1;
+
+    if (mRouteHandler->stop()) {
+        ALOGE("Unable to stop route NetlinkHandler: %s", strerror(errno));
+        status = -1;
+    }
+
+    delete mRouteHandler;
+    mRouteHandler = NULL;
+
+    close(mRouteSock);
+    mRouteSock = -1;
+
+    if (mQuotaHandler) {
+        if (mQuotaHandler->stop()) {
+            ALOGE("Unable to stop quota NetlinkHandler: %s", strerror(errno));
+            status = -1;
+        }
+
+        delete mQuotaHandler;
+        mQuotaHandler = NULL;
+
+        close(mQuotaSock);
+        mQuotaSock = -1;
+    }
+
+    if (mStrictHandler) {
+        if (mStrictHandler->stop()) {
+            ALOGE("Unable to stop strict NetlinkHandler: %s", strerror(errno));
+            status = -1;
+        }
+
+        delete mStrictHandler;
+        mStrictHandler = NULL;
+
+        close(mStrictSock);
+        mStrictSock = -1;
+    }
+
+    return status;
+}
diff --git a/netd/server/NetlinkManager.h b/netd/server/NetlinkManager.h
new file mode 100644
index 0000000..40a5722
--- /dev/null
+++ b/netd/server/NetlinkManager.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _NETLINKMANAGER_H
+#define _NETLINKMANAGER_H
+
+#include <sysutils/SocketListener.h>
+#include <sysutils/NetlinkListener.h>
+
+
+class NetlinkHandler;
+
+class NetlinkManager {
+private:
+    static NetlinkManager *sInstance;
+
+private:
+    SocketListener       *mBroadcaster;
+    NetlinkHandler       *mUeventHandler;
+    NetlinkHandler       *mRouteHandler;
+    NetlinkHandler       *mQuotaHandler;
+    NetlinkHandler       *mStrictHandler;
+    int                  mUeventSock;
+    int                  mRouteSock;
+    int                  mQuotaSock;
+    int                  mStrictSock;
+
+public:
+    virtual ~NetlinkManager();
+
+    int start();
+    int stop();
+
+    void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
+    SocketListener *getBroadcaster() { return mBroadcaster; }
+
+    static NetlinkManager *Instance();
+
+    /* Group used by xt_quota2 */
+    static const int NFLOG_QUOTA_GROUP;
+    /* Group used by StrictController rules */
+    static const int NETFILTER_STRICT_GROUP;
+
+private:
+    NetlinkManager();
+    NetlinkHandler* setupSocket(int *sock, int netlinkFamily, int groups,
+        int format, bool configNflog);
+};
+#endif
diff --git a/netd/server/Network.cpp b/netd/server/Network.cpp
new file mode 100644
index 0000000..0ca6247
--- /dev/null
+++ b/netd/server/Network.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 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 "Network.h"
+
+#define LOG_TAG "Netd"
+#include "log/log.h"
+
+Network::~Network() {
+    if (!mInterfaces.empty()) {
+        ALOGE("deleting network with netId %u without clearing its interfaces", mNetId);
+    }
+}
+
+unsigned Network::getNetId() const {
+    return mNetId;
+}
+
+bool Network::hasInterface(const std::string& interface) const {
+    return mInterfaces.find(interface) != mInterfaces.end();
+}
+
+const std::set<std::string>& Network::getInterfaces() const {
+    return mInterfaces;
+}
+
+int Network::clearInterfaces() {
+    while (!mInterfaces.empty()) {
+        // Make a copy of the string, so removeInterface() doesn't lose its parameter when it
+        // removes the string from the set.
+        std::string interface = *mInterfaces.begin();
+        if (int ret = removeInterface(interface)) {
+            return ret;
+        }
+    }
+    return 0;
+}
+
+Network::Network(unsigned netId) : mNetId(netId) {
+}
diff --git a/netd/server/Network.h b/netd/server/Network.h
new file mode 100644
index 0000000..3af53d9
--- /dev/null
+++ b/netd/server/Network.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_SERVER_NETWORK_H
+#define NETD_SERVER_NETWORK_H
+
+#include "NetdConstants.h"
+
+#include <set>
+#include <string>
+
+// A Network represents a collection of interfaces participating as a single administrative unit.
+class Network {
+public:
+    enum Type {
+        DUMMY,
+        LOCAL,
+        PHYSICAL,
+        VIRTUAL,
+    };
+
+    // You MUST ensure that no interfaces are still assigned to this network, say by calling
+    // clearInterfaces(), before deleting it. This is because interface removal may fail. If we
+    // automatically removed interfaces in the destructor, you wouldn't know if it failed.
+    virtual ~Network();
+
+    virtual Type getType() const = 0;
+    unsigned getNetId() const;
+
+    bool hasInterface(const std::string& interface) const;
+    const std::set<std::string>& getInterfaces() const;
+
+    // These return 0 on success or negative errno on failure.
+    virtual int addInterface(const std::string& interface) WARN_UNUSED_RESULT = 0;
+    virtual int removeInterface(const std::string& interface) WARN_UNUSED_RESULT = 0;
+    int clearInterfaces() WARN_UNUSED_RESULT;
+
+protected:
+    explicit Network(unsigned netId);
+
+    const unsigned mNetId;
+    std::set<std::string> mInterfaces;
+};
+
+#endif  // NETD_SERVER_NETWORK_H
diff --git a/netd/server/NetworkController.cpp b/netd/server/NetworkController.cpp
new file mode 100644
index 0000000..93a0763
--- /dev/null
+++ b/netd/server/NetworkController.cpp
@@ -0,0 +1,604 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// THREAD-SAFETY
+// -------------
+// The methods in this file are called from multiple threads (from CommandListener, FwmarkServer
+// and DnsProxyListener). So, all accesses to shared state are guarded by a lock.
+//
+// In some cases, a single non-const method acquires and releases the lock several times, like so:
+//     if (isValidNetwork(...)) {  // isValidNetwork() acquires and releases the lock.
+//        setDefaultNetwork(...);  // setDefaultNetwork() also acquires and releases the lock.
+//
+// It might seem that this allows races where the state changes between the two statements, but in
+// fact there are no races because:
+//     1. This pattern only occurs in non-const methods (i.e., those that mutate state).
+//     2. Only CommandListener calls these non-const methods. The others call only const methods.
+//     3. CommandListener only processes one command at a time. I.e., it's serialized.
+// Thus, no other mutation can occur in between the two statements above.
+
+#include "NetworkController.h"
+
+#include "DummyNetwork.h"
+#include "Fwmark.h"
+#include "LocalNetwork.h"
+#include "PhysicalNetwork.h"
+#include "RouteController.h"
+#include "VirtualNetwork.h"
+
+#include "cutils/misc.h"
+#define LOG_TAG "Netd"
+#include "log/log.h"
+#include "resolv_netid.h"
+
+namespace {
+
+// Keep these in sync with ConnectivityService.java.
+const unsigned MIN_NET_ID = 100;
+const unsigned MAX_NET_ID = 65535;
+
+}  // namespace
+
+const unsigned NetworkController::MIN_OEM_ID   =  1;
+const unsigned NetworkController::MAX_OEM_ID   = 50;
+const unsigned NetworkController::DUMMY_NET_ID = 51;
+// NetIds 52..98 are reserved for future use.
+const unsigned NetworkController::LOCAL_NET_ID = 99;
+
+// All calls to methods here are made while holding a write lock on mRWLock.
+class NetworkController::DelegateImpl : public PhysicalNetwork::Delegate {
+public:
+    explicit DelegateImpl(NetworkController* networkController);
+    virtual ~DelegateImpl();
+
+    int modifyFallthrough(unsigned vpnNetId, const std::string& physicalInterface,
+                          Permission permission, bool add) WARN_UNUSED_RESULT;
+
+private:
+    int addFallthrough(const std::string& physicalInterface,
+                       Permission permission) override WARN_UNUSED_RESULT;
+    int removeFallthrough(const std::string& physicalInterface,
+                          Permission permission) override WARN_UNUSED_RESULT;
+
+    int modifyFallthrough(const std::string& physicalInterface, Permission permission,
+                          bool add) WARN_UNUSED_RESULT;
+
+    NetworkController* const mNetworkController;
+};
+
+NetworkController::DelegateImpl::DelegateImpl(NetworkController* networkController) :
+        mNetworkController(networkController) {
+}
+
+NetworkController::DelegateImpl::~DelegateImpl() {
+}
+
+int NetworkController::DelegateImpl::modifyFallthrough(unsigned vpnNetId,
+                                                       const std::string& physicalInterface,
+                                                       Permission permission, bool add) {
+    if (add) {
+        if (int ret = RouteController::addVirtualNetworkFallthrough(vpnNetId,
+                                                                    physicalInterface.c_str(),
+                                                                    permission)) {
+            ALOGE("failed to add fallthrough to %s for VPN netId %u", physicalInterface.c_str(),
+                  vpnNetId);
+            return ret;
+        }
+    } else {
+        if (int ret = RouteController::removeVirtualNetworkFallthrough(vpnNetId,
+                                                                       physicalInterface.c_str(),
+                                                                       permission)) {
+            ALOGE("failed to remove fallthrough to %s for VPN netId %u", physicalInterface.c_str(),
+                  vpnNetId);
+            return ret;
+        }
+    }
+    return 0;
+}
+
+int NetworkController::DelegateImpl::addFallthrough(const std::string& physicalInterface,
+                                                    Permission permission) {
+    return modifyFallthrough(physicalInterface, permission, true);
+}
+
+int NetworkController::DelegateImpl::removeFallthrough(const std::string& physicalInterface,
+                                                       Permission permission) {
+    return modifyFallthrough(physicalInterface, permission, false);
+}
+
+int NetworkController::DelegateImpl::modifyFallthrough(const std::string& physicalInterface,
+                                                       Permission permission, bool add) {
+    for (const auto& entry : mNetworkController->mNetworks) {
+        if (entry.second->getType() == Network::VIRTUAL) {
+            if (int ret = modifyFallthrough(entry.first, physicalInterface, permission, add)) {
+                return ret;
+            }
+        }
+    }
+    return 0;
+}
+
+NetworkController::NetworkController() :
+        mDelegateImpl(new NetworkController::DelegateImpl(this)), mDefaultNetId(NETID_UNSET) {
+    mNetworks[LOCAL_NET_ID] = new LocalNetwork(LOCAL_NET_ID);
+    mNetworks[DUMMY_NET_ID] = new DummyNetwork(DUMMY_NET_ID);
+}
+
+unsigned NetworkController::getDefaultNetwork() const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    return mDefaultNetId;
+}
+
+int NetworkController::setDefaultNetwork(unsigned netId) {
+    android::RWLock::AutoWLock lock(mRWLock);
+
+    if (netId == mDefaultNetId) {
+        return 0;
+    }
+
+    if (netId != NETID_UNSET) {
+        Network* network = getNetworkLocked(netId);
+        if (!network) {
+            ALOGE("no such netId %u", netId);
+            return -ENONET;
+        }
+        if (network->getType() != Network::PHYSICAL) {
+            ALOGE("cannot set default to non-physical network with netId %u", netId);
+            return -EINVAL;
+        }
+        if (int ret = static_cast<PhysicalNetwork*>(network)->addAsDefault()) {
+            return ret;
+        }
+    }
+
+    if (mDefaultNetId != NETID_UNSET) {
+        Network* network = getNetworkLocked(mDefaultNetId);
+        if (!network || network->getType() != Network::PHYSICAL) {
+            ALOGE("cannot find previously set default network with netId %u", mDefaultNetId);
+            return -ESRCH;
+        }
+        if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
+            return ret;
+        }
+    }
+
+    mDefaultNetId = netId;
+    return 0;
+}
+
+uint32_t NetworkController::getNetworkForDns(unsigned* netId, uid_t uid) const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    Fwmark fwmark;
+    fwmark.protectedFromVpn = true;
+    fwmark.permission = PERMISSION_SYSTEM;
+    if (checkUserNetworkAccessLocked(uid, *netId) == 0) {
+        // If a non-zero NetId was explicitly specified, and the user has permission for that
+        // network, use that network's DNS servers. Do not fall through to the default network even
+        // if the explicitly selected network is a split tunnel VPN or a VPN without DNS servers.
+        fwmark.explicitlySelected = true;
+    } else {
+        // If the user is subject to a VPN and the VPN provides DNS servers, use those servers
+        // (possibly falling through to the default network if the VPN doesn't provide a route to
+        // them). Otherwise, use the default network's DNS servers.
+        VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
+        if (virtualNetwork && virtualNetwork->getHasDns()) {
+            *netId = virtualNetwork->getNetId();
+        } else {
+            *netId = mDefaultNetId;
+        }
+    }
+    fwmark.netId = *netId;
+    return fwmark.intValue;
+}
+
+// Returns the NetId that a given UID would use if no network is explicitly selected. Specifically,
+// the VPN that applies to the UID if any; otherwise, the default network.
+unsigned NetworkController::getNetworkForUser(uid_t uid) const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    if (VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid)) {
+        return virtualNetwork->getNetId();
+    }
+    return mDefaultNetId;
+}
+
+// Returns the NetId that will be set when a socket connect()s. This is the bypassable VPN that
+// applies to the user if any; otherwise, the default network.
+//
+// In general, we prefer to always set the default network's NetId in connect(), so that if the VPN
+// is a split-tunnel and disappears later, the socket continues working (since the default network's
+// NetId is still valid). Secure VPNs will correctly grab the socket's traffic since they have a
+// high-priority routing rule that doesn't care what NetId the socket has.
+//
+// But bypassable VPNs have a very low priority rule, so we need to mark the socket with the
+// bypassable VPN's NetId if we expect it to get any traffic at all. If the bypassable VPN is a
+// split-tunnel, that's okay, because we have fallthrough rules that will direct the fallthrough
+// traffic to the default network. But it does mean that if the bypassable VPN goes away (and thus
+// the fallthrough rules also go away), the socket that used to fallthrough to the default network
+// will stop working.
+unsigned NetworkController::getNetworkForConnect(uid_t uid) const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
+    if (virtualNetwork && !virtualNetwork->isSecure()) {
+        return virtualNetwork->getNetId();
+    }
+    return mDefaultNetId;
+}
+
+void NetworkController::getNetworkContext(
+        unsigned netId, uid_t uid, struct android_net_context* netcontext) const {
+    struct android_net_context nc = {
+            .app_netid = netId,
+            .app_mark = MARK_UNSET,
+            .dns_netid = netId,
+            .dns_mark = MARK_UNSET,
+            .uid = uid,
+    };
+
+    if (nc.app_netid == NETID_UNSET) {
+        nc.app_netid = getNetworkForConnect(uid);
+    }
+    Fwmark fwmark;
+    fwmark.netId = nc.app_netid;
+    nc.app_mark = fwmark.intValue;
+
+    nc.dns_mark = getNetworkForDns(&(nc.dns_netid), uid);
+
+    if (netcontext) {
+        *netcontext = nc;
+    }
+}
+
+unsigned NetworkController::getNetworkForInterface(const char* interface) const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    for (const auto& entry : mNetworks) {
+        if (entry.second->hasInterface(interface)) {
+            return entry.first;
+        }
+    }
+    return NETID_UNSET;
+}
+
+bool NetworkController::isVirtualNetwork(unsigned netId) const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    Network* network = getNetworkLocked(netId);
+    return network && network->getType() == Network::VIRTUAL;
+}
+
+int NetworkController::createPhysicalNetwork(unsigned netId, Permission permission) {
+    if (!((MIN_NET_ID <= netId && netId <= MAX_NET_ID) ||
+          (MIN_OEM_ID <= netId && netId <= MAX_OEM_ID))) {
+        ALOGE("invalid netId %u", netId);
+        return -EINVAL;
+    }
+
+    if (isValidNetwork(netId)) {
+        ALOGE("duplicate netId %u", netId);
+        return -EEXIST;
+    }
+
+    PhysicalNetwork* physicalNetwork = new PhysicalNetwork(netId, mDelegateImpl);
+    if (int ret = physicalNetwork->setPermission(permission)) {
+        ALOGE("inconceivable! setPermission cannot fail on an empty network");
+        delete physicalNetwork;
+        return ret;
+    }
+
+    android::RWLock::AutoWLock lock(mRWLock);
+    mNetworks[netId] = physicalNetwork;
+    return 0;
+}
+
+int NetworkController::createVirtualNetwork(unsigned netId, bool hasDns, bool secure) {
+    if (!(MIN_NET_ID <= netId && netId <= MAX_NET_ID)) {
+        ALOGE("invalid netId %u", netId);
+        return -EINVAL;
+    }
+
+    if (isValidNetwork(netId)) {
+        ALOGE("duplicate netId %u", netId);
+        return -EEXIST;
+    }
+
+    android::RWLock::AutoWLock lock(mRWLock);
+    if (int ret = modifyFallthroughLocked(netId, true)) {
+        return ret;
+    }
+    mNetworks[netId] = new VirtualNetwork(netId, hasDns, secure);
+    return 0;
+}
+
+int NetworkController::destroyNetwork(unsigned netId) {
+    if (netId == LOCAL_NET_ID) {
+        ALOGE("cannot destroy local network");
+        return -EINVAL;
+    }
+    if (!isValidNetwork(netId)) {
+        ALOGE("no such netId %u", netId);
+        return -ENONET;
+    }
+
+    // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network.
+
+    android::RWLock::AutoWLock lock(mRWLock);
+    Network* network = getNetworkLocked(netId);
+
+    // If we fail to destroy a network, things will get stuck badly. Therefore, unlike most of the
+    // other network code, ignore failures and attempt to clear out as much state as possible, even
+    // if we hit an error on the way. Return the first error that we see.
+    int ret = network->clearInterfaces();
+
+    if (mDefaultNetId == netId) {
+        if (int err = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
+            ALOGE("inconceivable! removeAsDefault cannot fail on an empty network");
+            if (!ret) {
+                ret = err;
+            }
+        }
+        mDefaultNetId = NETID_UNSET;
+    } else if (network->getType() == Network::VIRTUAL) {
+        if (int err = modifyFallthroughLocked(netId, false)) {
+            if (!ret) {
+                ret = err;
+            }
+        }
+    }
+    mNetworks.erase(netId);
+    delete network;
+    _resolv_delete_cache_for_net(netId);
+    return ret;
+}
+
+int NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) {
+    if (!isValidNetwork(netId)) {
+        ALOGE("no such netId %u", netId);
+        return -ENONET;
+    }
+
+    unsigned existingNetId = getNetworkForInterface(interface);
+    if (existingNetId != NETID_UNSET && existingNetId != netId) {
+        ALOGE("interface %s already assigned to netId %u", interface, existingNetId);
+        return -EBUSY;
+    }
+
+    android::RWLock::AutoWLock lock(mRWLock);
+    return getNetworkLocked(netId)->addInterface(interface);
+}
+
+int NetworkController::removeInterfaceFromNetwork(unsigned netId, const char* interface) {
+    if (!isValidNetwork(netId)) {
+        ALOGE("no such netId %u", netId);
+        return -ENONET;
+    }
+
+    android::RWLock::AutoWLock lock(mRWLock);
+    return getNetworkLocked(netId)->removeInterface(interface);
+}
+
+Permission NetworkController::getPermissionForUser(uid_t uid) const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    return getPermissionForUserLocked(uid);
+}
+
+void NetworkController::setPermissionForUsers(Permission permission,
+                                              const std::vector<uid_t>& uids) {
+    android::RWLock::AutoWLock lock(mRWLock);
+    for (uid_t uid : uids) {
+        mUsers[uid] = permission;
+    }
+}
+
+int NetworkController::checkUserNetworkAccess(uid_t uid, unsigned netId) const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    return checkUserNetworkAccessLocked(uid, netId);
+}
+
+int NetworkController::setPermissionForNetworks(Permission permission,
+                                                const std::vector<unsigned>& netIds) {
+    android::RWLock::AutoWLock lock(mRWLock);
+    for (unsigned netId : netIds) {
+        Network* network = getNetworkLocked(netId);
+        if (!network) {
+            ALOGE("no such netId %u", netId);
+            return -ENONET;
+        }
+        if (network->getType() != Network::PHYSICAL) {
+            ALOGE("cannot set permissions on non-physical network with netId %u", netId);
+            return -EINVAL;
+        }
+
+        // TODO: ioctl(SIOCKILLADDR, ...) to kill socets on the network that don't have permission.
+
+        if (int ret = static_cast<PhysicalNetwork*>(network)->setPermission(permission)) {
+            return ret;
+        }
+    }
+    return 0;
+}
+
+int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) {
+    android::RWLock::AutoWLock lock(mRWLock);
+    Network* network = getNetworkLocked(netId);
+    if (!network) {
+        ALOGE("no such netId %u", netId);
+        return -ENONET;
+    }
+    if (network->getType() != Network::VIRTUAL) {
+        ALOGE("cannot add users to non-virtual network with netId %u", netId);
+        return -EINVAL;
+    }
+    if (int ret = static_cast<VirtualNetwork*>(network)->addUsers(uidRanges)) {
+        return ret;
+    }
+    return 0;
+}
+
+int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) {
+    android::RWLock::AutoWLock lock(mRWLock);
+    Network* network = getNetworkLocked(netId);
+    if (!network) {
+        ALOGE("no such netId %u", netId);
+        return -ENONET;
+    }
+    if (network->getType() != Network::VIRTUAL) {
+        ALOGE("cannot remove users from non-virtual network with netId %u", netId);
+        return -EINVAL;
+    }
+    if (int ret = static_cast<VirtualNetwork*>(network)->removeUsers(uidRanges)) {
+        return ret;
+    }
+    return 0;
+}
+
+int NetworkController::addRoute(unsigned netId, const char* interface, const char* destination,
+                                const char* nexthop, bool legacy, uid_t uid) {
+    return modifyRoute(netId, interface, destination, nexthop, true, legacy, uid);
+}
+
+int NetworkController::removeRoute(unsigned netId, const char* interface, const char* destination,
+                                   const char* nexthop, bool legacy, uid_t uid) {
+    return modifyRoute(netId, interface, destination, nexthop, false, legacy, uid);
+}
+
+bool NetworkController::canProtect(uid_t uid) const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    return ((getPermissionForUserLocked(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) ||
+           mProtectableUsers.find(uid) != mProtectableUsers.end();
+}
+
+void NetworkController::allowProtect(const std::vector<uid_t>& uids) {
+    android::RWLock::AutoWLock lock(mRWLock);
+    mProtectableUsers.insert(uids.begin(), uids.end());
+}
+
+void NetworkController::denyProtect(const std::vector<uid_t>& uids) {
+    android::RWLock::AutoWLock lock(mRWLock);
+    for (uid_t uid : uids) {
+        mProtectableUsers.erase(uid);
+    }
+}
+
+bool NetworkController::isValidNetwork(unsigned netId) const {
+    android::RWLock::AutoRLock lock(mRWLock);
+    return getNetworkLocked(netId);
+}
+
+Network* NetworkController::getNetworkLocked(unsigned netId) const {
+    auto iter = mNetworks.find(netId);
+    return iter == mNetworks.end() ? NULL : iter->second;
+}
+
+VirtualNetwork* NetworkController::getVirtualNetworkForUserLocked(uid_t uid) const {
+    for (const auto& entry : mNetworks) {
+        if (entry.second->getType() == Network::VIRTUAL) {
+            VirtualNetwork* virtualNetwork = static_cast<VirtualNetwork*>(entry.second);
+            if (virtualNetwork->appliesToUser(uid)) {
+                return virtualNetwork;
+            }
+        }
+    }
+    return NULL;
+}
+
+Permission NetworkController::getPermissionForUserLocked(uid_t uid) const {
+    auto iter = mUsers.find(uid);
+    if (iter != mUsers.end()) {
+        return iter->second;
+    }
+    return uid < FIRST_APPLICATION_UID ? PERMISSION_SYSTEM : PERMISSION_NONE;
+}
+
+int NetworkController::checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const {
+    Network* network = getNetworkLocked(netId);
+    if (!network) {
+        return -ENONET;
+    }
+
+    // If uid is INVALID_UID, this likely means that we were unable to retrieve the UID of the peer
+    // (using SO_PEERCRED). Be safe and deny access to the network, even if it's valid.
+    if (uid == INVALID_UID) {
+        return -EREMOTEIO;
+    }
+    Permission userPermission = getPermissionForUserLocked(uid);
+    if ((userPermission & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
+        return 0;
+    }
+    if (network->getType() == Network::VIRTUAL) {
+        return static_cast<VirtualNetwork*>(network)->appliesToUser(uid) ? 0 : -EPERM;
+    }
+    VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
+    if (virtualNetwork && virtualNetwork->isSecure() &&
+            mProtectableUsers.find(uid) == mProtectableUsers.end()) {
+        return -EPERM;
+    }
+    Permission networkPermission = static_cast<PhysicalNetwork*>(network)->getPermission();
+    return ((userPermission & networkPermission) == networkPermission) ? 0 : -EACCES;
+}
+
+int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination,
+                                   const char* nexthop, bool add, bool legacy, uid_t uid) {
+    if (!isValidNetwork(netId)) {
+        ALOGE("no such netId %u", netId);
+        return -ENONET;
+    }
+    unsigned existingNetId = getNetworkForInterface(interface);
+    if (existingNetId == NETID_UNSET) {
+        ALOGE("interface %s not assigned to any netId", interface);
+        return -ENODEV;
+    }
+    if (existingNetId != netId) {
+        ALOGE("interface %s assigned to netId %u, not %u", interface, existingNetId, netId);
+        return -ENOENT;
+    }
+
+    RouteController::TableType tableType;
+    if (netId == LOCAL_NET_ID) {
+        tableType = RouteController::LOCAL_NETWORK;
+    } else if (legacy) {
+        if ((getPermissionForUser(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
+            tableType = RouteController::LEGACY_SYSTEM;
+        } else {
+            tableType = RouteController::LEGACY_NETWORK;
+        }
+    } else {
+        tableType = RouteController::INTERFACE;
+    }
+
+    return add ? RouteController::addRoute(interface, destination, nexthop, tableType) :
+                 RouteController::removeRoute(interface, destination, nexthop, tableType);
+}
+
+int NetworkController::modifyFallthroughLocked(unsigned vpnNetId, bool add) {
+    if (mDefaultNetId == NETID_UNSET) {
+        return 0;
+    }
+    Network* network = getNetworkLocked(mDefaultNetId);
+    if (!network) {
+        ALOGE("cannot find previously set default network with netId %u", mDefaultNetId);
+        return -ESRCH;
+    }
+    if (network->getType() != Network::PHYSICAL) {
+        ALOGE("inconceivable! default network must be a physical network");
+        return -EINVAL;
+    }
+    Permission permission = static_cast<PhysicalNetwork*>(network)->getPermission();
+    for (const auto& physicalInterface : network->getInterfaces()) {
+        if (int ret = mDelegateImpl->modifyFallthrough(vpnNetId, physicalInterface, permission,
+                                                       add)) {
+            return ret;
+        }
+    }
+    return 0;
+}
diff --git a/netd/server/NetworkController.h b/netd/server/NetworkController.h
new file mode 100644
index 0000000..6d72aeb
--- /dev/null
+++ b/netd/server/NetworkController.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_SERVER_NETWORK_CONTROLLER_H
+#define NETD_SERVER_NETWORK_CONTROLLER_H
+
+#include "NetdConstants.h"
+#include "Permission.h"
+
+#include "utils/RWLock.h"
+
+#include <list>
+#include <map>
+#include <set>
+#include <sys/types.h>
+#include <vector>
+
+class Network;
+class UidRanges;
+class VirtualNetwork;
+
+/*
+ * Keeps track of default, per-pid, and per-uid-range network selection, as
+ * well as the mark associated with each network. Networks are identified
+ * by netid. In all set* commands netid == 0 means "unspecified" and is
+ * equivalent to clearing the mapping.
+ */
+class NetworkController {
+public:
+    static const unsigned MIN_OEM_ID;
+    static const unsigned MAX_OEM_ID;
+    static const unsigned LOCAL_NET_ID;
+    static const unsigned DUMMY_NET_ID;
+
+    NetworkController();
+
+    unsigned getDefaultNetwork() const;
+    int setDefaultNetwork(unsigned netId) WARN_UNUSED_RESULT;
+
+    // Sets |*netId| to an appropriate NetId to use for DNS for the given user. Call with |*netId|
+    // set to a non-NETID_UNSET value if the user already has indicated a preference. Returns the
+    // fwmark value to set on the socket when performing the DNS request.
+    uint32_t getNetworkForDns(unsigned* netId, uid_t uid) const;
+    unsigned getNetworkForUser(uid_t uid) const;
+    unsigned getNetworkForConnect(uid_t uid) const;
+    void getNetworkContext(unsigned netId, uid_t uid, struct android_net_context* netcontext) const;
+    unsigned getNetworkForInterface(const char* interface) const;
+    bool isVirtualNetwork(unsigned netId) const;
+
+    int createPhysicalNetwork(unsigned netId, Permission permission) WARN_UNUSED_RESULT;
+    int createVirtualNetwork(unsigned netId, bool hasDns, bool secure) WARN_UNUSED_RESULT;
+    int destroyNetwork(unsigned netId) WARN_UNUSED_RESULT;
+
+    int addInterfaceToNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT;
+    int removeInterfaceFromNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT;
+
+    Permission getPermissionForUser(uid_t uid) const;
+    void setPermissionForUsers(Permission permission, const std::vector<uid_t>& uids);
+    int checkUserNetworkAccess(uid_t uid, unsigned netId) const;
+    int setPermissionForNetworks(Permission permission,
+                                 const std::vector<unsigned>& netIds) WARN_UNUSED_RESULT;
+
+    int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+    int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+
+    // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
+    // route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
+    //
+    // Routes are added to tables determined by the interface, so only |interface| is actually used.
+    // |netId| is given only to sanity check that the interface has the correct netId.
+    int addRoute(unsigned netId, const char* interface, const char* destination,
+                 const char* nexthop, bool legacy, uid_t uid) WARN_UNUSED_RESULT;
+    int removeRoute(unsigned netId, const char* interface, const char* destination,
+                    const char* nexthop, bool legacy, uid_t uid) WARN_UNUSED_RESULT;
+
+    bool canProtect(uid_t uid) const;
+    void allowProtect(const std::vector<uid_t>& uids);
+    void denyProtect(const std::vector<uid_t>& uids);
+
+private:
+    bool isValidNetwork(unsigned netId) const;
+    Network* getNetworkLocked(unsigned netId) const;
+    VirtualNetwork* getVirtualNetworkForUserLocked(uid_t uid) const;
+    Permission getPermissionForUserLocked(uid_t uid) const;
+    int checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const;
+
+    int modifyRoute(unsigned netId, const char* interface, const char* destination,
+                    const char* nexthop, bool add, bool legacy, uid_t uid) WARN_UNUSED_RESULT;
+    int modifyFallthroughLocked(unsigned vpnNetId, bool add) WARN_UNUSED_RESULT;
+
+    class DelegateImpl;
+    DelegateImpl* const mDelegateImpl;
+
+    // mRWLock guards all accesses to mDefaultNetId, mNetworks, mUsers and mProtectableUsers.
+    mutable android::RWLock mRWLock;
+    unsigned mDefaultNetId;
+    std::map<unsigned, Network*> mNetworks;  // Map keys are NetIds.
+    std::map<uid_t, Permission> mUsers;
+    std::set<uid_t> mProtectableUsers;
+};
+
+#endif  // NETD_SERVER_NETWORK_CONTROLLER_H
diff --git a/netd/server/PhysicalNetwork.cpp b/netd/server/PhysicalNetwork.cpp
new file mode 100644
index 0000000..495a93a
--- /dev/null
+++ b/netd/server/PhysicalNetwork.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2014 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 "PhysicalNetwork.h"
+
+#include "RouteController.h"
+
+#define LOG_TAG "Netd"
+#include "log/log.h"
+
+namespace {
+
+WARN_UNUSED_RESULT int addToDefault(unsigned netId, const std::string& interface,
+                                    Permission permission, PhysicalNetwork::Delegate* delegate) {
+    if (int ret = RouteController::addInterfaceToDefaultNetwork(interface.c_str(), permission)) {
+        ALOGE("failed to add interface %s to default netId %u", interface.c_str(), netId);
+        return ret;
+    }
+    if (int ret = delegate->addFallthrough(interface, permission)) {
+        return ret;
+    }
+    return 0;
+}
+
+WARN_UNUSED_RESULT int removeFromDefault(unsigned netId, const std::string& interface,
+                                         Permission permission,
+                                         PhysicalNetwork::Delegate* delegate) {
+    if (int ret = RouteController::removeInterfaceFromDefaultNetwork(interface.c_str(),
+                                                                     permission)) {
+        ALOGE("failed to remove interface %s from default netId %u", interface.c_str(), netId);
+        return ret;
+    }
+    if (int ret = delegate->removeFallthrough(interface, permission)) {
+        return ret;
+    }
+    return 0;
+}
+
+}  // namespace
+
+PhysicalNetwork::Delegate::~Delegate() {
+}
+
+PhysicalNetwork::PhysicalNetwork(unsigned netId, PhysicalNetwork::Delegate* delegate) :
+        Network(netId), mDelegate(delegate), mPermission(PERMISSION_NONE), mIsDefault(false) {
+}
+
+PhysicalNetwork::~PhysicalNetwork() {
+}
+
+Permission PhysicalNetwork::getPermission() const {
+    return mPermission;
+}
+
+int PhysicalNetwork::setPermission(Permission permission) {
+    if (permission == mPermission) {
+        return 0;
+    }
+    for (const std::string& interface : mInterfaces) {
+        if (int ret = RouteController::modifyPhysicalNetworkPermission(mNetId, interface.c_str(),
+                                                                       mPermission, permission)) {
+            ALOGE("failed to change permission on interface %s of netId %u from %x to %x",
+                  interface.c_str(), mNetId, mPermission, permission);
+            return ret;
+        }
+    }
+    if (mIsDefault) {
+        for (const std::string& interface : mInterfaces) {
+            if (int ret = addToDefault(mNetId, interface, permission, mDelegate)) {
+                return ret;
+            }
+            if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
+                return ret;
+            }
+        }
+    }
+    mPermission = permission;
+    return 0;
+}
+
+int PhysicalNetwork::addAsDefault() {
+    if (mIsDefault) {
+        return 0;
+    }
+    for (const std::string& interface : mInterfaces) {
+        if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
+            return ret;
+        }
+    }
+    mIsDefault = true;
+    return 0;
+}
+
+int PhysicalNetwork::removeAsDefault() {
+    if (!mIsDefault) {
+        return 0;
+    }
+    for (const std::string& interface : mInterfaces) {
+        if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
+            return ret;
+        }
+    }
+    mIsDefault = false;
+    return 0;
+}
+
+Network::Type PhysicalNetwork::getType() const {
+    return PHYSICAL;
+}
+
+int PhysicalNetwork::addInterface(const std::string& interface) {
+    if (hasInterface(interface)) {
+        return 0;
+    }
+    if (int ret = RouteController::addInterfaceToPhysicalNetwork(mNetId, interface.c_str(),
+                                                                 mPermission)) {
+        ALOGE("failed to add interface %s to netId %u", interface.c_str(), mNetId);
+        return ret;
+    }
+    if (mIsDefault) {
+        if (int ret = addToDefault(mNetId, interface, mPermission, mDelegate)) {
+            return ret;
+        }
+    }
+    mInterfaces.insert(interface);
+    return 0;
+}
+
+int PhysicalNetwork::removeInterface(const std::string& interface) {
+    if (!hasInterface(interface)) {
+        return 0;
+    }
+    if (mIsDefault) {
+        if (int ret = removeFromDefault(mNetId, interface, mPermission, mDelegate)) {
+            return ret;
+        }
+    }
+    // This step will flush the interface index from the cache in RouteController so it must be
+    // done last as further requests to the RouteController regarding this interface will fail
+    // to find the interface index in the cache in cases where the interface is already gone
+    // (e.g. bt-pan).
+    if (int ret = RouteController::removeInterfaceFromPhysicalNetwork(mNetId, interface.c_str(),
+                                                                      mPermission)) {
+        ALOGE("failed to remove interface %s from netId %u", interface.c_str(), mNetId);
+        return ret;
+    }
+    mInterfaces.erase(interface);
+    return 0;
+}
diff --git a/netd/server/PhysicalNetwork.h b/netd/server/PhysicalNetwork.h
new file mode 100644
index 0000000..2ef10df
--- /dev/null
+++ b/netd/server/PhysicalNetwork.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_SERVER_PHYSICAL_NETWORK_H
+#define NETD_SERVER_PHYSICAL_NETWORK_H
+
+#include "Network.h"
+#include "Permission.h"
+
+class PhysicalNetwork : public Network {
+public:
+    class Delegate {
+    public:
+        virtual ~Delegate();
+
+        virtual int addFallthrough(const std::string& physicalInterface,
+                                   Permission permission) WARN_UNUSED_RESULT = 0;
+        virtual int removeFallthrough(const std::string& physicalInterface,
+                                      Permission permission) WARN_UNUSED_RESULT = 0;
+    };
+
+    PhysicalNetwork(unsigned netId, Delegate* delegate);
+    virtual ~PhysicalNetwork();
+
+    // These refer to permissions that apps must have in order to use this network.
+    Permission getPermission() const;
+    int setPermission(Permission permission) WARN_UNUSED_RESULT;
+
+    int addAsDefault() WARN_UNUSED_RESULT;
+    int removeAsDefault() WARN_UNUSED_RESULT;
+
+private:
+    Type getType() const override;
+    int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+    int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+
+    Delegate* const mDelegate;
+    Permission mPermission;
+    bool mIsDefault;
+};
+
+#endif  // NETD_SERVER_PHYSICAL_NETWORK_H
diff --git a/netd/server/PppController.cpp b/netd/server/PppController.cpp
new file mode 100644
index 0000000..581b9c6
--- /dev/null
+++ b/netd/server/PppController.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008 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 <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <dirent.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define LOG_TAG "PppController"
+#include <cutils/log.h>
+
+#include "PppController.h"
+
+PppController::PppController() {
+    mTtys = new TtyCollection();
+    mPid = 0;
+}
+
+PppController::~PppController() {
+    TtyCollection::iterator it;
+
+    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
+        free(*it);
+    }
+    mTtys->clear();
+}
+
+int PppController::attachPppd(const char *tty, struct in_addr local,
+                              struct in_addr remote, struct in_addr dns1,
+                              struct in_addr dns2) {
+    pid_t pid;
+
+    if (mPid) {
+        ALOGE("Multiple PPPD instances not currently supported");
+        errno = EBUSY;
+        return -1;
+    }
+
+    TtyCollection::iterator it;
+    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
+        if (!strcmp(tty, *it)) {
+            break;
+        }
+    }
+    if (it == mTtys->end()) {
+        ALOGE("Invalid tty '%s' specified", tty);
+        errno = -EINVAL;
+        return -1;
+    }
+
+    if ((pid = fork()) < 0) {
+        ALOGE("fork failed (%s)", strerror(errno));
+        return -1;
+    }
+
+    if (!pid) {
+        char *l = strdup(inet_ntoa(local));
+        char *r = strdup(inet_ntoa(remote));
+        char *d1 = strdup(inet_ntoa(dns1));
+        char *d2 = strdup(inet_ntoa(dns2));
+        char dev[32];
+        char *lr;
+
+        asprintf(&lr, "%s:%s", l, r);
+        free(l);
+        free(r);
+
+        snprintf(dev, sizeof(dev), "/dev/%s", tty);
+
+        // TODO: Deal with pppd bailing out after 99999 seconds of being started
+        // but not getting a connection
+        if (execl("/system/bin/pppd", "/system/bin/pppd", "-detach", dev, "115200",
+                  lr, "ms-dns", d1, "ms-dns", d2, "lcp-max-configure", "99999", (char *) NULL)) {
+            ALOGE("execl failed (%s)", strerror(errno));
+        }
+        free(lr);
+        free(d1);
+        free(d2);
+        ALOGE("Should never get here!");
+        return 0;
+    } else {
+        mPid = pid;
+    }
+    return 0;
+}
+
+int PppController::detachPppd(const char *tty) {
+
+    if (mPid == 0) {
+        ALOGE("PPPD already stopped");
+        return 0;
+    }
+
+    ALOGD("Stopping PPPD services on port %s", tty);
+    kill(mPid, SIGTERM);
+    waitpid(mPid, NULL, 0);
+    mPid = 0;
+    ALOGD("PPPD services on port %s stopped", tty);
+    return 0;
+}
+
+TtyCollection *PppController::getTtyList() {
+    updateTtyList();
+    return mTtys;
+}
+
+int PppController::updateTtyList() {
+    TtyCollection::iterator it;
+
+    for (it = mTtys->begin(); it != mTtys->end(); ++it) {
+        free(*it);
+    }
+    mTtys->clear();
+
+    DIR *d = opendir("/sys/class/tty");
+    if (!d) {
+        ALOGE("Error opening /sys/class/tty (%s)", strerror(errno));
+        return -1;
+    }
+
+    struct dirent *de;
+    while ((de = readdir(d))) {
+        if (de->d_name[0] == '.')
+            continue;
+        if ((!strncmp(de->d_name, "tty", 3)) && (strlen(de->d_name) > 3)) {
+            mTtys->push_back(strdup(de->d_name));
+        }
+    }
+    closedir(d);
+    return 0;
+}
diff --git a/netd/server/PppController.h b/netd/server/PppController.h
new file mode 100644
index 0000000..cc74c8c
--- /dev/null
+++ b/netd/server/PppController.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _PPP_CONTROLLER_H
+#define _PPP_CONTROLLER_H
+
+#include <linux/in.h>
+
+#include "List.h"
+
+typedef android::netd::List<char *> TtyCollection;
+
+class PppController {
+    TtyCollection *mTtys;
+    pid_t          mPid; // TODO: Add support for > 1 pppd instance
+
+public:
+    PppController();
+    virtual ~PppController();
+
+    int attachPppd(const char *tty, struct in_addr local,
+                   struct in_addr remote, struct in_addr dns1,
+                   struct in_addr dns2);
+    int detachPppd(const char *tty);
+    TtyCollection *getTtyList();
+
+private:
+    int updateTtyList();
+};
+
+#endif
diff --git a/netd/server/ResolverController.cpp b/netd/server/ResolverController.cpp
new file mode 100644
index 0000000..16cfd53
--- /dev/null
+++ b/netd/server/ResolverController.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "ResolverController"
+#define DBG 0
+
+#include <cutils/log.h>
+
+#include <net/if.h>
+
+// NOTE: <resolv_netid.h> is a private C library header that provides
+//       declarations for _resolv_set_nameservers_for_net and
+//       _resolv_flush_cache_for_net
+#include <resolv_netid.h>
+#include <resolv_params.h>
+
+#include "ResolverController.h"
+
+int ResolverController::setDnsServers(unsigned netId, const char* searchDomains,
+        const char** servers, int numservers, const __res_params* params) {
+    if (DBG) {
+        ALOGD("setDnsServers netId = %u\n", netId);
+    }
+    _resolv_set_nameservers_for_net(netId, servers, numservers, searchDomains, params);
+    return 0;
+}
+
+int ResolverController::clearDnsServers(unsigned netId) {
+    _resolv_set_nameservers_for_net(netId, NULL, 0, "", NULL);
+    if (DBG) {
+        ALOGD("clearDnsServers netId = %u\n", netId);
+    }
+    return 0;
+}
+
+int ResolverController::flushDnsCache(unsigned netId) {
+    if (DBG) {
+        ALOGD("flushDnsCache netId = %u\n", netId);
+    }
+
+    _resolv_flush_cache_for_net(netId);
+
+    return 0;
+}
diff --git a/netd/server/ResolverController.h b/netd/server/ResolverController.h
new file mode 100644
index 0000000..048ff3f
--- /dev/null
+++ b/netd/server/ResolverController.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef _RESOLVER_CONTROLLER_H_
+#define _RESOLVER_CONTROLLER_H_
+
+#include <netinet/in.h>
+#include <linux/in.h>
+
+struct __res_params;
+
+class ResolverController {
+public:
+    ResolverController() {};
+    virtual ~ResolverController() {};
+    int setDnsServers(unsigned netId, const char* searchDomains, const char** servers,
+            int numservers, const __res_params* params);
+    int clearDnsServers(unsigned netid);
+    int flushDnsCache(unsigned netid);
+    // TODO: Add deleteDnsCache(unsigned netId)
+};
+
+#endif /* _RESOLVER_CONTROLLER_H_ */
diff --git a/netd/server/ResponseCode.h b/netd/server/ResponseCode.h
new file mode 100644
index 0000000..19d76c3
--- /dev/null
+++ b/netd/server/ResponseCode.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _RESPONSECODE_H
+#define _RESPONSECODE_H
+
+class ResponseCode {
+    // Keep in sync with
+    // frameworks/base/services/java/com/android/server/NetworkManagementService.java
+public:
+    // 100 series - Requestion action was initiated; expect another reply
+    // before proceeding with a new command.
+    static const int ActionInitiated           = 100;
+    static const int InterfaceListResult       = 110;
+    static const int TetherInterfaceListResult = 111;
+    static const int TetherDnsFwdTgtListResult = 112;
+    static const int TtyListResult             = 113;
+    static const int TetheringStatsListResult  = 114;
+    static const int TetherDnsFwdNetIdResult   = 115;
+
+    // 200 series - Requested action has been successfully completed
+    static const int CommandOkay               = 200;
+    static const int TetherStatusResult        = 210;
+    static const int IpFwdStatusResult         = 211;
+    static const int InterfaceGetCfgResult     = 213;
+    static const int SoftapStatusResult        = 214;
+    static const int UsbRNDISStatusResult      = 215;
+    static const int InterfaceRxCounterResult  = 216;
+    static const int InterfaceTxCounterResult  = 217;
+    static const int InterfaceRxThrottleResult = 218;
+    static const int InterfaceTxThrottleResult = 219;
+    static const int QuotaCounterResult        = 220;
+    static const int TetheringStatsResult      = 221;
+    static const int DnsProxyQueryResult       = 222;
+    static const int ClatdStatusResult         = 223;
+
+    // 400 series - The command was accepted but the requested action
+    // did not take place.
+    static const int OperationFailed           = 400;
+    static const int DnsProxyOperationFailed   = 401;
+    static const int ServiceStartFailed        = 402;
+    static const int ServiceStopFailed         = 403;
+
+    // 500 series - The command was not accepted and the requested
+    // action did not take place.
+    static const int CommandSyntaxError = 500;
+    static const int CommandParameterError = 501;
+
+    // 600 series - Unsolicited broadcasts
+    static const int InterfaceChange                = 600;
+    static const int BandwidthControl               = 601;
+    static const int ServiceDiscoveryFailed         = 602;
+    static const int ServiceDiscoveryServiceAdded   = 603;
+    static const int ServiceDiscoveryServiceRemoved = 604;
+    static const int ServiceRegistrationFailed      = 605;
+    static const int ServiceRegistrationSucceeded   = 606;
+    static const int ServiceResolveFailed           = 607;
+    static const int ServiceResolveSuccess          = 608;
+    static const int ServiceSetHostnameFailed       = 609;
+    static const int ServiceSetHostnameSuccess      = 610;
+    static const int ServiceGetAddrInfoFailed       = 611;
+    static const int ServiceGetAddrInfoSuccess      = 612;
+    static const int InterfaceClassActivity         = 613;
+    static const int InterfaceAddressChange         = 614;
+    static const int InterfaceDnsInfo               = 615;
+    static const int RouteChange                    = 616;
+    static const int StrictCleartext                = 617;
+};
+#endif
diff --git a/netd/server/RouteController.cpp b/netd/server/RouteController.cpp
new file mode 100644
index 0000000..e4b7cc1
--- /dev/null
+++ b/netd/server/RouteController.cpp
@@ -0,0 +1,1091 @@
+/*
+ * Copyright (C) 2014 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 "RouteController.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/fib_rules.h>
+#include <net/if.h>
+#include <sys/stat.h>
+
+#include <private/android_filesystem_config.h>
+
+#include <map>
+
+#include "Fwmark.h"
+#include "UidRanges.h"
+#include "DummyNetwork.h"
+
+#include "android-base/file.h"
+#define LOG_TAG "Netd"
+#include "log/log.h"
+#include "logwrap/logwrap.h"
+#include "netutils/ifc.h"
+#include "resolv_netid.h"
+
+using android::base::WriteStringToFile;
+
+namespace {
+
+// BEGIN CONSTANTS --------------------------------------------------------------------------------
+
+const uint32_t RULE_PRIORITY_VPN_OVERRIDE_SYSTEM = 10000;
+const uint32_t RULE_PRIORITY_VPN_OVERRIDE_OIF    = 10500;
+const uint32_t RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL = 11000;
+const uint32_t RULE_PRIORITY_SECURE_VPN          = 12000;
+const uint32_t RULE_PRIORITY_EXPLICIT_NETWORK    = 13000;
+const uint32_t RULE_PRIORITY_OUTPUT_INTERFACE    = 14000;
+const uint32_t RULE_PRIORITY_LEGACY_SYSTEM       = 15000;
+const uint32_t RULE_PRIORITY_LEGACY_NETWORK      = 16000;
+const uint32_t RULE_PRIORITY_LOCAL_NETWORK       = 17000;
+const uint32_t RULE_PRIORITY_TETHERING           = 18000;
+const uint32_t RULE_PRIORITY_IMPLICIT_NETWORK    = 19000;
+const uint32_t RULE_PRIORITY_BYPASSABLE_VPN      = 20000;
+const uint32_t RULE_PRIORITY_VPN_FALLTHROUGH     = 21000;
+const uint32_t RULE_PRIORITY_DEFAULT_NETWORK     = 22000;
+const uint32_t RULE_PRIORITY_DIRECTLY_CONNECTED  = 23000;
+const uint32_t RULE_PRIORITY_UNREACHABLE         = 32000;
+
+const uint32_t ROUTE_TABLE_LOCAL_NETWORK  = 97;
+const uint32_t ROUTE_TABLE_LEGACY_NETWORK = 98;
+const uint32_t ROUTE_TABLE_LEGACY_SYSTEM  = 99;
+
+const char* const ROUTE_TABLE_NAME_LOCAL_NETWORK  = "local_network";
+const char* const ROUTE_TABLE_NAME_LEGACY_NETWORK = "legacy_network";
+const char* const ROUTE_TABLE_NAME_LEGACY_SYSTEM  = "legacy_system";
+
+const char* const ROUTE_TABLE_NAME_LOCAL = "local";
+const char* const ROUTE_TABLE_NAME_MAIN  = "main";
+
+// TODO: These values aren't defined by the Linux kernel, because our UID routing changes are not
+// upstream (yet?), so we can't just pick them up from kernel headers. When (if?) the changes make
+// it upstream, we'll remove this and rely on the kernel header values. For now, add a static assert
+// that will warn us if upstream has given these values some other meaning.
+const uint16_t FRA_UID_START = 18;
+const uint16_t FRA_UID_END   = 19;
+static_assert(FRA_UID_START > FRA_MAX,
+             "Android-specific FRA_UID_{START,END} values also assigned in Linux uapi. "
+             "Check that these values match what the kernel does and then update this assertion.");
+
+const uint16_t NETLINK_REQUEST_FLAGS = NLM_F_REQUEST | NLM_F_ACK;
+const uint16_t NETLINK_CREATE_REQUEST_FLAGS = NETLINK_REQUEST_FLAGS | NLM_F_CREATE | NLM_F_EXCL;
+
+const sockaddr_nl NETLINK_ADDRESS = {AF_NETLINK, 0, 0, 0};
+
+const uint8_t AF_FAMILIES[] = {AF_INET, AF_INET6};
+
+const char* const IP_VERSIONS[] = {"-4", "-6"};
+
+const uid_t UID_ROOT = 0;
+const char* const IIF_LOOPBACK = "lo";
+const char* const IIF_NONE = NULL;
+const char* const OIF_NONE = NULL;
+const bool ACTION_ADD = true;
+const bool ACTION_DEL = false;
+const bool MODIFY_NON_UID_BASED_RULES = true;
+
+const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables";
+const mode_t RT_TABLES_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;  // mode 0644, rw-r--r--
+
+const unsigned ROUTE_FLUSH_ATTEMPTS = 2;
+
+// Avoids "non-constant-expression cannot be narrowed from type 'unsigned int' to 'unsigned short'"
+// warnings when using RTA_LENGTH(x) inside static initializers (even when x is already uint16_t).
+constexpr uint16_t U16_RTA_LENGTH(uint16_t x) {
+    return RTA_LENGTH(x);
+}
+
+// These are practically const, but can't be declared so, because they are used to initialize
+// non-const pointers ("void* iov_base") in iovec arrays.
+rtattr FRATTR_PRIORITY  = { U16_RTA_LENGTH(sizeof(uint32_t)), FRA_PRIORITY };
+rtattr FRATTR_TABLE     = { U16_RTA_LENGTH(sizeof(uint32_t)), FRA_TABLE };
+rtattr FRATTR_FWMARK    = { U16_RTA_LENGTH(sizeof(uint32_t)), FRA_FWMARK };
+rtattr FRATTR_FWMASK    = { U16_RTA_LENGTH(sizeof(uint32_t)), FRA_FWMASK };
+rtattr FRATTR_UID_START = { U16_RTA_LENGTH(sizeof(uid_t)),    FRA_UID_START };
+rtattr FRATTR_UID_END   = { U16_RTA_LENGTH(sizeof(uid_t)),    FRA_UID_END };
+
+rtattr RTATTR_TABLE     = { U16_RTA_LENGTH(sizeof(uint32_t)), RTA_TABLE };
+rtattr RTATTR_OIF       = { U16_RTA_LENGTH(sizeof(uint32_t)), RTA_OIF };
+
+uint8_t PADDING_BUFFER[RTA_ALIGNTO] = {0, 0, 0, 0};
+
+// END CONSTANTS ----------------------------------------------------------------------------------
+
+// No locks needed because RouteController is accessed only from one thread (in CommandListener).
+std::map<std::string, uint32_t> interfaceToTable;
+
+uint32_t getRouteTableForInterface(const char* interface) {
+    uint32_t index = if_nametoindex(interface);
+    if (index) {
+        index += RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX;
+        interfaceToTable[interface] = index;
+        return index;
+    }
+    // If the interface goes away if_nametoindex() will return 0 but we still need to know
+    // the index so we can remove the rules and routes.
+    auto iter = interfaceToTable.find(interface);
+    if (iter == interfaceToTable.end()) {
+        ALOGE("cannot find interface %s", interface);
+        return RT_TABLE_UNSPEC;
+    }
+    return iter->second;
+}
+
+void addTableName(uint32_t table, const std::string& name, std::string* contents) {
+    char tableString[UINT32_STRLEN];
+    snprintf(tableString, sizeof(tableString), "%u", table);
+    *contents += tableString;
+    *contents += " ";
+    *contents += name;
+    *contents += "\n";
+}
+
+// Doesn't return success/failure as the file is optional; it's okay if we fail to update it.
+void updateTableNamesFile() {
+    std::string contents;
+
+    addTableName(RT_TABLE_LOCAL, ROUTE_TABLE_NAME_LOCAL, &contents);
+    addTableName(RT_TABLE_MAIN,  ROUTE_TABLE_NAME_MAIN,  &contents);
+
+    addTableName(ROUTE_TABLE_LOCAL_NETWORK,  ROUTE_TABLE_NAME_LOCAL_NETWORK,  &contents);
+    addTableName(ROUTE_TABLE_LEGACY_NETWORK, ROUTE_TABLE_NAME_LEGACY_NETWORK, &contents);
+    addTableName(ROUTE_TABLE_LEGACY_SYSTEM,  ROUTE_TABLE_NAME_LEGACY_SYSTEM,  &contents);
+
+    for (const auto& entry : interfaceToTable) {
+        addTableName(entry.second, entry.first, &contents);
+    }
+
+    if (!WriteStringToFile(contents, RT_TABLES_PATH, RT_TABLES_MODE, AID_SYSTEM, AID_WIFI)) {
+        ALOGE("failed to write to %s (%s)", RT_TABLES_PATH, strerror(errno));
+        return;
+    }
+}
+
+// Sends a netlink request and expects an ack.
+// |iov| is an array of struct iovec that contains the netlink message payload.
+// The netlink header is generated by this function based on |action| and |flags|.
+// Returns -errno if there was an error or if the kernel reported an error.
+
+// Disable optimizations in ASan build.
+// ASan reports an out-of-bounds 32-bit(!) access in the first loop of the
+// function (over iov[]).
+#ifdef __clang__
+#if __has_feature(address_sanitizer)
+__attribute__((optnone))
+#endif
+#endif
+WARN_UNUSED_RESULT int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen) {
+    nlmsghdr nlmsg = {
+        .nlmsg_type = action,
+        .nlmsg_flags = flags,
+    };
+    iov[0].iov_base = &nlmsg;
+    iov[0].iov_len = sizeof(nlmsg);
+    for (int i = 0; i < iovlen; ++i) {
+        nlmsg.nlmsg_len += iov[i].iov_len;
+    }
+
+    int ret;
+    struct {
+        nlmsghdr msg;
+        nlmsgerr err;
+    } response;
+
+    int sock = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
+    if (sock != -1 &&
+            connect(sock, reinterpret_cast<const sockaddr*>(&NETLINK_ADDRESS),
+                    sizeof(NETLINK_ADDRESS)) != -1 &&
+            writev(sock, iov, iovlen) != -1 &&
+            (ret = recv(sock, &response, sizeof(response), 0)) != -1) {
+        if (ret == sizeof(response)) {
+            ret = response.err.error;  // Netlink errors are negative errno.
+            if (ret) {
+                ALOGE("netlink response contains error (%s)", strerror(-ret));
+            }
+        } else {
+            ALOGE("bad netlink response message size (%d != %zu)", ret, sizeof(response));
+            ret = -EBADMSG;
+        }
+    } else {
+        ALOGE("netlink socket/connect/writev/recv failed (%s)", strerror(errno));
+        ret = -errno;
+    }
+
+    if (sock != -1) {
+        close(sock);
+    }
+
+    return ret;
+}
+
+// Returns 0 on success or negative errno on failure.
+int padInterfaceName(const char* input, char* name, size_t* length, uint16_t* padding) {
+    if (!input) {
+        *length = 0;
+        *padding = 0;
+        return 0;
+    }
+    *length = strlcpy(name, input, IFNAMSIZ) + 1;
+    if (*length > IFNAMSIZ) {
+        ALOGE("interface name too long (%zu > %u)", *length, IFNAMSIZ);
+        return -ENAMETOOLONG;
+    }
+    *padding = RTA_SPACE(*length) - RTA_LENGTH(*length);
+    return 0;
+}
+
+// Adds or removes a routing rule for IPv4 and IPv6.
+//
+// + If |priority| is RULE_PRIORITY_UNREACHABLE, the rule returns ENETUNREACH (i.e., specifies an
+//   action of FR_ACT_UNREACHABLE). Otherwise, the rule specifies an action of FR_ACT_TO_TBL.
+// + If |table| is non-zero, the rule points at the specified routing table. Otherwise, the table is
+//   unspecified. An unspecified table is only allowed when deleting a rule.
+// + If |mask| is non-zero, the rule matches the specified fwmark and mask. Otherwise, |fwmark| is
+//   ignored.
+// + If |iif| is non-NULL, the rule matches the specified incoming interface.
+// + If |oif| is non-NULL, the rule matches the specified outgoing interface.
+// + If |uidStart| and |uidEnd| are not INVALID_UID, the rule matches packets from UIDs in that
+//   range (inclusive). Otherwise, the rule matches packets from all UIDs.
+//
+// Returns 0 on success or negative errno on failure.
+WARN_UNUSED_RESULT int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table,
+                                    uint32_t fwmark, uint32_t mask, const char* iif,
+                                    const char* oif, uid_t uidStart, uid_t uidEnd) {
+    // Ensure that if you set a bit in the fwmark, it's not being ignored by the mask.
+    if (fwmark & ~mask) {
+        ALOGE("mask 0x%x does not select all the bits set in fwmark 0x%x", mask, fwmark);
+        return -ERANGE;
+    }
+
+    // Interface names must include exactly one terminating NULL and be properly padded, or older
+    // kernels will refuse to delete rules.
+    char iifName[IFNAMSIZ], oifName[IFNAMSIZ];
+    size_t iifLength, oifLength;
+    uint16_t iifPadding, oifPadding;
+    if (int ret = padInterfaceName(iif, iifName, &iifLength, &iifPadding)) {
+        return ret;
+    }
+    if (int ret = padInterfaceName(oif, oifName, &oifLength, &oifPadding)) {
+        return ret;
+    }
+
+    // Either both start and end UID must be specified, or neither.
+    if ((uidStart == INVALID_UID) != (uidEnd == INVALID_UID)) {
+        ALOGE("incompatible start and end UIDs (%u vs %u)", uidStart, uidEnd);
+        return -EUSERS;
+    }
+    bool isUidRule = (uidStart != INVALID_UID);
+
+    // Assemble a rule request and put it in an array of iovec structures.
+    fib_rule_hdr rule = {
+        .action = static_cast<uint8_t>(priority != RULE_PRIORITY_UNREACHABLE ? FR_ACT_TO_TBL :
+                                                                               FR_ACT_UNREACHABLE),
+        // Note that here we're implicitly setting rule.table to 0. When we want to specify a
+        // non-zero table, we do this via the FRATTR_TABLE attribute.
+    };
+
+    // Don't ever create a rule that looks up table 0, because table 0 is the local table.
+    // It's OK to specify a table ID of 0 when deleting a rule, because that doesn't actually select
+    // table 0, it's a wildcard that matches anything.
+    if (table == RT_TABLE_UNSPEC && rule.action == FR_ACT_TO_TBL && action != RTM_DELRULE) {
+        ALOGE("RT_TABLE_UNSPEC only allowed when deleting rules");
+        return -ENOTUNIQ;
+    }
+
+    rtattr fraIifName = { U16_RTA_LENGTH(iifLength), FRA_IIFNAME };
+    rtattr fraOifName = { U16_RTA_LENGTH(oifLength), FRA_OIFNAME };
+
+    iovec iov[] = {
+        { NULL,              0 },
+        { &rule,             sizeof(rule) },
+        { &FRATTR_PRIORITY,  sizeof(FRATTR_PRIORITY) },
+        { &priority,         sizeof(priority) },
+        { &FRATTR_TABLE,     table != RT_TABLE_UNSPEC ? sizeof(FRATTR_TABLE) : 0 },
+        { &table,            table != RT_TABLE_UNSPEC ? sizeof(table) : 0 },
+        { &FRATTR_FWMARK,    mask ? sizeof(FRATTR_FWMARK) : 0 },
+        { &fwmark,           mask ? sizeof(fwmark) : 0 },
+        { &FRATTR_FWMASK,    mask ? sizeof(FRATTR_FWMASK) : 0 },
+        { &mask,             mask ? sizeof(mask) : 0 },
+        { &FRATTR_UID_START, isUidRule ? sizeof(FRATTR_UID_START) : 0 },
+        { &uidStart,         isUidRule ? sizeof(uidStart) : 0 },
+        { &FRATTR_UID_END,   isUidRule ? sizeof(FRATTR_UID_END) : 0 },
+        { &uidEnd,           isUidRule ? sizeof(uidEnd) : 0 },
+        { &fraIifName,       iif != IIF_NONE ? sizeof(fraIifName) : 0 },
+        { iifName,           iifLength },
+        { PADDING_BUFFER,    iifPadding },
+        { &fraOifName,       oif != OIF_NONE ? sizeof(fraOifName) : 0 },
+        { oifName,           oifLength },
+        { PADDING_BUFFER,    oifPadding },
+    };
+
+    uint16_t flags = (action == RTM_NEWRULE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS;
+    for (size_t i = 0; i < ARRAY_SIZE(AF_FAMILIES); ++i) {
+        rule.family = AF_FAMILIES[i];
+        if (int ret = sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov))) {
+            return ret;
+        }
+    }
+
+    return 0;
+}
+
+WARN_UNUSED_RESULT int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table,
+                                    uint32_t fwmark, uint32_t mask) {
+    return modifyIpRule(action, priority, table, fwmark, mask, IIF_NONE, OIF_NONE, INVALID_UID,
+                        INVALID_UID);
+}
+
+// Adds or deletes an IPv4 or IPv6 route.
+// Returns 0 on success or negative errno on failure.
+WARN_UNUSED_RESULT int modifyIpRoute(uint16_t action, uint32_t table, const char* interface,
+                                     const char* destination, const char* nexthop) {
+    // At least the destination must be non-null.
+    if (!destination) {
+        ALOGE("null destination");
+        return -EFAULT;
+    }
+
+    // Parse the prefix.
+    uint8_t rawAddress[sizeof(in6_addr)];
+    uint8_t family;
+    uint8_t prefixLength;
+    int rawLength = parsePrefix(destination, &family, rawAddress, sizeof(rawAddress),
+                                &prefixLength);
+    if (rawLength < 0) {
+        ALOGE("parsePrefix failed for destination %s (%s)", destination, strerror(-rawLength));
+        return rawLength;
+    }
+
+    if (static_cast<size_t>(rawLength) > sizeof(rawAddress)) {
+        ALOGE("impossible! address too long (%d vs %zu)", rawLength, sizeof(rawAddress));
+        return -ENOBUFS;  // Cannot happen; parsePrefix only supports IPv4 and IPv6.
+    }
+
+    uint8_t type = RTN_UNICAST;
+    uint32_t ifindex;
+    uint8_t rawNexthop[sizeof(in6_addr)];
+
+    if (nexthop && !strcmp(nexthop, "unreachable")) {
+        type = RTN_UNREACHABLE;
+        // 'interface' is likely non-NULL, as the caller (modifyRoute()) likely used it to lookup
+        // the table number. But it's an error to specify an interface ("dev ...") or a nexthop for
+        // unreachable routes, so nuke them. (IPv6 allows them to be specified; IPv4 doesn't.)
+        interface = OIF_NONE;
+        nexthop = NULL;
+    } else if (nexthop && !strcmp(nexthop, "throw")) {
+        type = RTN_THROW;
+        interface = OIF_NONE;
+        nexthop = NULL;
+    } else {
+        // If an interface was specified, find the ifindex.
+        if (interface != OIF_NONE) {
+            ifindex = if_nametoindex(interface);
+            if (!ifindex) {
+                ALOGE("cannot find interface %s", interface);
+                return -ENODEV;
+            }
+        }
+
+        // If a nexthop was specified, parse it as the same family as the prefix.
+        if (nexthop && inet_pton(family, nexthop, rawNexthop) <= 0) {
+            ALOGE("inet_pton failed for nexthop %s", nexthop);
+            return -EINVAL;
+        }
+    }
+
+    // Assemble a rtmsg and put it in an array of iovec structures.
+    rtmsg route = {
+        .rtm_protocol = RTPROT_STATIC,
+        .rtm_type = type,
+        .rtm_family = family,
+        .rtm_dst_len = prefixLength,
+        .rtm_scope = static_cast<uint8_t>(nexthop ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK),
+    };
+
+    rtattr rtaDst     = { U16_RTA_LENGTH(rawLength), RTA_DST };
+    rtattr rtaGateway = { U16_RTA_LENGTH(rawLength), RTA_GATEWAY };
+
+    iovec iov[] = {
+        { NULL,          0 },
+        { &route,        sizeof(route) },
+        { &RTATTR_TABLE, sizeof(RTATTR_TABLE) },
+        { &table,        sizeof(table) },
+        { &rtaDst,       sizeof(rtaDst) },
+        { rawAddress,    static_cast<size_t>(rawLength) },
+        { &RTATTR_OIF,   interface != OIF_NONE ? sizeof(RTATTR_OIF) : 0 },
+        { &ifindex,      interface != OIF_NONE ? sizeof(ifindex) : 0 },
+        { &rtaGateway,   nexthop ? sizeof(rtaGateway) : 0 },
+        { rawNexthop,    nexthop ? static_cast<size_t>(rawLength) : 0 },
+    };
+
+    uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS :
+                                                NETLINK_REQUEST_FLAGS;
+    return sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov));
+}
+
+// An iptables rule to mark incoming packets on a network with the netId of the network.
+//
+// This is so that the kernel can:
+// + Use the right fwmark for (and thus correctly route) replies (e.g.: TCP RST, ICMP errors, ping
+//   replies, SYN-ACKs, etc).
+// + Mark sockets that accept connections from this interface so that the connection stays on the
+//   same interface.
+WARN_UNUSED_RESULT int modifyIncomingPacketMark(unsigned netId, const char* interface,
+                                                Permission permission, bool add) {
+    Fwmark fwmark;
+
+    fwmark.netId = netId;
+    fwmark.explicitlySelected = true;
+    fwmark.protectedFromVpn = true;
+    fwmark.permission = permission;
+
+    char markString[UINT32_HEX_STRLEN];
+    snprintf(markString, sizeof(markString), "0x%x", fwmark.intValue);
+
+    if (execIptables(V4V6, "-t", "mangle", add ? "-A" : "-D", "INPUT", "-i", interface, "-j",
+                     "MARK", "--set-mark", markString, NULL)) {
+        ALOGE("failed to change iptables rule that sets incoming packet mark");
+        return -EREMOTEIO;
+    }
+
+    return 0;
+}
+
+// A rule to route responses to the local network forwarded via the VPN.
+//
+// When a VPN is in effect, packets from the local network to upstream networks are forwarded into
+// the VPN's tunnel interface. When the VPN forwards the responses, they emerge out of the tunnel.
+WARN_UNUSED_RESULT int modifyVpnOutputToLocalRule(const char* vpnInterface, bool add) {
+    return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL,
+                        ROUTE_TABLE_LOCAL_NETWORK, MARK_UNSET, MARK_UNSET, vpnInterface, OIF_NONE,
+                        INVALID_UID, INVALID_UID);
+}
+
+// A rule to route all traffic from a given set of UIDs to go over the VPN.
+//
+// Notice that this rule doesn't use the netId. I.e., no matter what netId the user's socket may
+// have, if they are subject to this VPN, their traffic has to go through it. Allows the traffic to
+// bypass the VPN if the protectedFromVpn bit is set.
+WARN_UNUSED_RESULT int modifyVpnUidRangeRule(uint32_t table, uid_t uidStart, uid_t uidEnd,
+                                             bool secure, bool add) {
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.protectedFromVpn = false;
+    mask.protectedFromVpn = true;
+
+    uint32_t priority;
+
+    if (secure) {
+        priority = RULE_PRIORITY_SECURE_VPN;
+    } else {
+        priority = RULE_PRIORITY_BYPASSABLE_VPN;
+
+        fwmark.explicitlySelected = false;
+        mask.explicitlySelected = true;
+    }
+
+    return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, priority, table, fwmark.intValue,
+                        mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd);
+}
+
+// A rule to allow system apps to send traffic over this VPN even if they are not part of the target
+// set of UIDs.
+//
+// This is needed for DnsProxyListener to correctly resolve a request for a user who is in the
+// target set, but where the DnsProxyListener itself is not.
+WARN_UNUSED_RESULT int modifyVpnSystemPermissionRule(unsigned netId, uint32_t table, bool secure,
+                                                     bool add) {
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.netId = netId;
+    mask.netId = FWMARK_NET_ID_MASK;
+
+    fwmark.permission = PERMISSION_SYSTEM;
+    mask.permission = PERMISSION_SYSTEM;
+
+    uint32_t priority = secure ? RULE_PRIORITY_SECURE_VPN : RULE_PRIORITY_BYPASSABLE_VPN;
+
+    return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, priority, table, fwmark.intValue,
+                        mask.intValue);
+}
+
+// A rule to route traffic based on an explicitly chosen network.
+//
+// Supports apps that use the multinetwork APIs to restrict their traffic to a network.
+//
+// Even though we check permissions at the time we set a netId into the fwmark of a socket, we need
+// to check it again in the rules here, because a network's permissions may have been updated via
+// modifyNetworkPermission().
+WARN_UNUSED_RESULT int modifyExplicitNetworkRule(unsigned netId, uint32_t table,
+                                                 Permission permission, uid_t uidStart,
+                                                 uid_t uidEnd, bool add) {
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.netId = netId;
+    mask.netId = FWMARK_NET_ID_MASK;
+
+    fwmark.explicitlySelected = true;
+    mask.explicitlySelected = true;
+
+    fwmark.permission = permission;
+    mask.permission = permission;
+
+    return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_EXPLICIT_NETWORK, table,
+                        fwmark.intValue, mask.intValue, IIF_NONE, OIF_NONE, uidStart, uidEnd);
+}
+
+// A rule to route traffic based on a chosen outgoing interface.
+//
+// Supports apps that use SO_BINDTODEVICE or IP_PKTINFO options and the kernel that already knows
+// the outgoing interface (typically for link-local communications).
+WARN_UNUSED_RESULT int modifyOutputInterfaceRules(const char* interface, uint32_t table,
+                                                  Permission permission, uid_t uidStart,
+                                                  uid_t uidEnd, bool add) {
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.permission = permission;
+    mask.permission = permission;
+
+    // If this rule does not specify a UID range, then also add a corresponding high-priority rule
+    // for UID. This covers forwarded packets and system daemons such as the tethering DHCP server.
+    if (uidStart == INVALID_UID && uidEnd == INVALID_UID) {
+        if (int ret = modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_VPN_OVERRIDE_OIF,
+                                   table, fwmark.intValue, mask.intValue, IIF_NONE, interface,
+                                   UID_ROOT, UID_ROOT)) {
+            return ret;
+        }
+    }
+
+    return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_OUTPUT_INTERFACE, table,
+                        fwmark.intValue, mask.intValue, IIF_NONE, interface, uidStart, uidEnd);
+}
+
+// A rule to route traffic based on the chosen network.
+//
+// This is for sockets that have not explicitly requested a particular network, but have been
+// bound to one when they called connect(). This ensures that sockets connected on a particular
+// network stay on that network even if the default network changes.
+WARN_UNUSED_RESULT int modifyImplicitNetworkRule(unsigned netId, uint32_t table,
+                                                 Permission permission, bool add) {
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.netId = netId;
+    mask.netId = FWMARK_NET_ID_MASK;
+
+    fwmark.explicitlySelected = false;
+    mask.explicitlySelected = true;
+
+    fwmark.permission = permission;
+    mask.permission = permission;
+
+    return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_IMPLICIT_NETWORK, table,
+                        fwmark.intValue, mask.intValue);
+}
+
+// A rule to enable split tunnel VPNs.
+//
+// If a packet with a VPN's netId doesn't find a route in the VPN's routing table, it's allowed to
+// go over the default network, provided it wasn't explicitly restricted to the VPN and has the
+// permissions required by the default network.
+WARN_UNUSED_RESULT int modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
+                                                const char* physicalInterface,
+                                                Permission permission) {
+    uint32_t table = getRouteTableForInterface(physicalInterface);
+    if (table == RT_TABLE_UNSPEC) {
+        return -ESRCH;
+    }
+
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.netId = vpnNetId;
+    mask.netId = FWMARK_NET_ID_MASK;
+
+    fwmark.explicitlySelected = false;
+    mask.explicitlySelected = true;
+
+    fwmark.permission = permission;
+    mask.permission = permission;
+
+    return modifyIpRule(action, RULE_PRIORITY_VPN_FALLTHROUGH, table, fwmark.intValue,
+                        mask.intValue);
+}
+
+// Add rules to allow legacy routes added through the requestRouteToHost() API.
+WARN_UNUSED_RESULT int addLegacyRouteRules() {
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.explicitlySelected = false;
+    mask.explicitlySelected = true;
+
+    // Rules to allow legacy routes to override the default network.
+    if (int ret = modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_LEGACY_SYSTEM, ROUTE_TABLE_LEGACY_SYSTEM,
+                               fwmark.intValue, mask.intValue)) {
+        return ret;
+    }
+    if (int ret = modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_LEGACY_NETWORK,
+                               ROUTE_TABLE_LEGACY_NETWORK, fwmark.intValue, mask.intValue)) {
+        return ret;
+    }
+
+    fwmark.permission = PERMISSION_SYSTEM;
+    mask.permission = PERMISSION_SYSTEM;
+
+    // A rule to allow legacy routes from system apps to override VPNs.
+    return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_VPN_OVERRIDE_SYSTEM, ROUTE_TABLE_LEGACY_SYSTEM,
+                        fwmark.intValue, mask.intValue);
+}
+
+// Add rules to lookup the local network when specified explicitly or otherwise.
+WARN_UNUSED_RESULT int addLocalNetworkRules(unsigned localNetId) {
+    if (int ret = modifyExplicitNetworkRule(localNetId, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
+                                            INVALID_UID, INVALID_UID, ACTION_ADD)) {
+        return ret;
+    }
+
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.explicitlySelected = false;
+    mask.explicitlySelected = true;
+
+    return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_LOCAL_NETWORK, ROUTE_TABLE_LOCAL_NETWORK,
+                        fwmark.intValue, mask.intValue);
+}
+
+int configureDummyNetwork() {
+    const char *interface = DummyNetwork::INTERFACE_NAME;
+    uint32_t table = getRouteTableForInterface(interface);
+    if (table == RT_TABLE_UNSPEC) {
+        // getRouteTableForInterface has already looged an error.
+        return -ESRCH;
+    }
+
+    ifc_init();
+    int ret = ifc_up(interface);
+    ifc_close();
+    if (ret) {
+        ALOGE("Can't bring up %s: %s", interface, strerror(errno));
+        return -errno;
+    }
+
+    if ((ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE,
+                                          INVALID_UID, INVALID_UID, ACTION_ADD))) {
+        ALOGE("Can't create oif rules for %s: %s", interface, strerror(-ret));
+        return ret;
+    }
+
+    if ((ret = modifyIpRoute(RTM_NEWROUTE, table, interface, "0.0.0.0/0", NULL))) {
+        ALOGE("Can't add IPv4 default route to %s: %s", interface, strerror(-ret));
+        return ret;
+    }
+
+    if ((ret = modifyIpRoute(RTM_NEWROUTE, table, interface, "::/0", NULL))) {
+        ALOGE("Can't add IPv6 default route to %s: %s", interface, strerror(-ret));
+        return ret;
+    }
+
+    return 0;
+}
+
+// Add a new rule to look up the 'main' table, with the same selectors as the "default network"
+// rule, but with a lower priority. We will never create routes in the main table; it should only be
+// used for directly-connected routes implicitly created by the kernel when adding IP addresses.
+// This is necessary, for example, when adding a route through a directly-connected gateway: in
+// order to add the route, there must already be a directly-connected route that covers the gateway.
+WARN_UNUSED_RESULT int addDirectlyConnectedRule() {
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.netId = NETID_UNSET;
+    mask.netId = FWMARK_NET_ID_MASK;
+
+    return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_DIRECTLY_CONNECTED, RT_TABLE_MAIN,
+                        fwmark.intValue, mask.intValue, IIF_NONE, OIF_NONE, UID_ROOT, UID_ROOT);
+}
+
+// Add an explicit unreachable rule close to the end of the prioriy list to make it clear that
+// relying on the kernel-default "from all lookup main" rule at priority 32766 is not intended
+// behaviour. We do flush the kernel-default rules at startup, but having an explicit unreachable
+// rule will hopefully make things even clearer.
+WARN_UNUSED_RESULT int addUnreachableRule() {
+    return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_UNREACHABLE, RT_TABLE_UNSPEC, MARK_UNSET,
+                        MARK_UNSET);
+}
+
+WARN_UNUSED_RESULT int modifyLocalNetwork(unsigned netId, const char* interface, bool add) {
+    if (int ret = modifyIncomingPacketMark(netId, interface, PERMISSION_NONE, add)) {
+        return ret;
+    }
+    return modifyOutputInterfaceRules(interface, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
+                                      INVALID_UID, INVALID_UID, add);
+}
+
+WARN_UNUSED_RESULT int modifyPhysicalNetwork(unsigned netId, const char* interface,
+                                             Permission permission, bool add) {
+    uint32_t table = getRouteTableForInterface(interface);
+    if (table == RT_TABLE_UNSPEC) {
+        return -ESRCH;
+    }
+
+    if (int ret = modifyIncomingPacketMark(netId, interface, permission, add)) {
+        return ret;
+    }
+    if (int ret = modifyExplicitNetworkRule(netId, table, permission, INVALID_UID, INVALID_UID,
+                                            add)) {
+        return ret;
+    }
+    if (int ret = modifyOutputInterfaceRules(interface, table, permission, INVALID_UID, INVALID_UID,
+                                            add)) {
+        return ret;
+    }
+    return modifyImplicitNetworkRule(netId, table, permission, add);
+}
+
+WARN_UNUSED_RESULT int modifyVirtualNetwork(unsigned netId, const char* interface,
+                                            const UidRanges& uidRanges, bool secure, bool add,
+                                            bool modifyNonUidBasedRules) {
+    uint32_t table = getRouteTableForInterface(interface);
+    if (table == RT_TABLE_UNSPEC) {
+        return -ESRCH;
+    }
+
+    for (const UidRanges::Range& range : uidRanges.getRanges()) {
+        if (int ret = modifyVpnUidRangeRule(table, range.first, range.second, secure, add)) {
+            return ret;
+        }
+        if (int ret = modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, range.first,
+                                                range.second, add)) {
+            return ret;
+        }
+        if (int ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE, range.first,
+                                                 range.second, add)) {
+            return ret;
+        }
+    }
+
+    if (modifyNonUidBasedRules) {
+        if (int ret = modifyIncomingPacketMark(netId, interface, PERMISSION_NONE, add)) {
+            return ret;
+        }
+        if (int ret = modifyVpnOutputToLocalRule(interface, add)) {
+            return ret;
+        }
+        if (int ret = modifyVpnSystemPermissionRule(netId, table, secure, add)) {
+            return ret;
+        }
+        return modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT, add);
+    }
+
+    return 0;
+}
+
+WARN_UNUSED_RESULT int modifyDefaultNetwork(uint16_t action, const char* interface,
+                                            Permission permission) {
+    uint32_t table = getRouteTableForInterface(interface);
+    if (table == RT_TABLE_UNSPEC) {
+        return -ESRCH;
+    }
+
+    Fwmark fwmark;
+    Fwmark mask;
+
+    fwmark.netId = NETID_UNSET;
+    mask.netId = FWMARK_NET_ID_MASK;
+
+    fwmark.permission = permission;
+    mask.permission = permission;
+
+    return modifyIpRule(action, RULE_PRIORITY_DEFAULT_NETWORK, table, fwmark.intValue,
+                        mask.intValue);
+}
+
+WARN_UNUSED_RESULT int modifyTetheredNetwork(uint16_t action, const char* inputInterface,
+                                             const char* outputInterface) {
+    uint32_t table = getRouteTableForInterface(outputInterface);
+    if (table == RT_TABLE_UNSPEC) {
+        return -ESRCH;
+    }
+
+    return modifyIpRule(action, RULE_PRIORITY_TETHERING, table, MARK_UNSET, MARK_UNSET,
+                        inputInterface, OIF_NONE, INVALID_UID, INVALID_UID);
+}
+
+// Returns 0 on success or negative errno on failure.
+WARN_UNUSED_RESULT int flushRules() {
+    for (size_t i = 0; i < ARRAY_SIZE(IP_VERSIONS); ++i) {
+        const char* argv[] = {
+            IP_PATH,
+            IP_VERSIONS[i],
+            "rule",
+            "flush",
+        };
+        if (android_fork_execvp(ARRAY_SIZE(argv), const_cast<char**>(argv), NULL, false, false)) {
+            ALOGE("failed to flush rules");
+            return -EREMOTEIO;
+        }
+    }
+    return 0;
+}
+
+// Adds or removes an IPv4 or IPv6 route to the specified table and, if it's a directly-connected
+// route, to the main table as well.
+// Returns 0 on success or negative errno on failure.
+WARN_UNUSED_RESULT int modifyRoute(uint16_t action, const char* interface, const char* destination,
+                                   const char* nexthop, RouteController::TableType tableType) {
+    uint32_t table;
+    switch (tableType) {
+        case RouteController::INTERFACE: {
+            table = getRouteTableForInterface(interface);
+            if (table == RT_TABLE_UNSPEC) {
+                return -ESRCH;
+            }
+            break;
+        }
+        case RouteController::LOCAL_NETWORK: {
+            table = ROUTE_TABLE_LOCAL_NETWORK;
+            break;
+        }
+        case RouteController::LEGACY_NETWORK: {
+            table = ROUTE_TABLE_LEGACY_NETWORK;
+            break;
+        }
+        case RouteController::LEGACY_SYSTEM: {
+            table = ROUTE_TABLE_LEGACY_SYSTEM;
+            break;
+        }
+    }
+
+    int ret = modifyIpRoute(action, table, interface, destination, nexthop);
+    // Trying to add a route that already exists shouldn't cause an error.
+    if (ret && !(action == RTM_NEWROUTE && ret == -EEXIST)) {
+        return ret;
+    }
+
+    return 0;
+}
+
+// Returns 0 on success or negative errno on failure.
+WARN_UNUSED_RESULT int flushRoutes(const char* interface) {
+    uint32_t table = getRouteTableForInterface(interface);
+    if (table == RT_TABLE_UNSPEC) {
+        return -ESRCH;
+    }
+
+    char tableString[UINT32_STRLEN];
+    snprintf(tableString, sizeof(tableString), "%u", table);
+
+    int ret = 0;
+    for (size_t i = 0; i < ARRAY_SIZE(IP_VERSIONS); ++i) {
+        const char* argv[] = {
+            IP_PATH,
+            IP_VERSIONS[i],
+            "route",
+            "flush",
+            "table",
+            tableString,
+        };
+
+        // A flush works by dumping routes and deleting each route as it's returned, and it can
+        // fail if something else deletes the route between the dump and the delete. This can
+        // happen, for example, if an interface goes down while we're trying to flush its routes.
+        // So try multiple times and only return an error if the last attempt fails.
+        //
+        // TODO: replace this with our own netlink code.
+        unsigned attempts = 0;
+        int err;
+        do {
+            err = android_fork_execvp(ARRAY_SIZE(argv), const_cast<char**>(argv),
+                                      NULL, false, false);
+            ++attempts;
+        } while (err != 0 && attempts < ROUTE_FLUSH_ATTEMPTS);
+        if (err) {
+            ALOGE("failed to flush %s routes in table %s after %d attempts",
+                  IP_VERSIONS[i], tableString, attempts);
+            ret = -EREMOTEIO;
+        }
+    }
+
+    // If we failed to flush routes, the caller may elect to keep this interface around, so keep
+    // track of its name.
+    if (!ret) {
+        interfaceToTable.erase(interface);
+    }
+
+    return ret;
+}
+
+WARN_UNUSED_RESULT int clearTetheringRules(const char* inputInterface) {
+    int ret = 0;
+    while (ret == 0) {
+        ret = modifyIpRule(RTM_DELRULE, RULE_PRIORITY_TETHERING, 0, MARK_UNSET, MARK_UNSET,
+                           inputInterface, OIF_NONE, INVALID_UID, INVALID_UID);
+    }
+
+    if (ret == -ENOENT) {
+        return 0;
+    } else {
+        return ret;
+    }
+}
+
+}  // namespace
+
+int RouteController::Init(unsigned localNetId) {
+    if (int ret = flushRules()) {
+        return ret;
+    }
+    if (int ret = addLegacyRouteRules()) {
+        return ret;
+    }
+    if (int ret = addLocalNetworkRules(localNetId)) {
+        return ret;
+    }
+    if (int ret = addDirectlyConnectedRule()) {
+        return ret;
+    }
+    if (int ret = addUnreachableRule()) {
+        return ret;
+    }
+    // Don't complain if we can't add the dummy network, since not all devices support it.
+    configureDummyNetwork();
+
+    updateTableNamesFile();
+    return 0;
+}
+
+int RouteController::addInterfaceToLocalNetwork(unsigned netId, const char* interface) {
+    return modifyLocalNetwork(netId, interface, ACTION_ADD);
+}
+
+int RouteController::removeInterfaceFromLocalNetwork(unsigned netId, const char* interface) {
+    return modifyLocalNetwork(netId, interface, ACTION_DEL);
+}
+
+int RouteController::addInterfaceToPhysicalNetwork(unsigned netId, const char* interface,
+                                                   Permission permission) {
+    if (int ret = modifyPhysicalNetwork(netId, interface, permission, ACTION_ADD)) {
+        return ret;
+    }
+    updateTableNamesFile();
+    return 0;
+}
+
+int RouteController::removeInterfaceFromPhysicalNetwork(unsigned netId, const char* interface,
+                                                        Permission permission) {
+    if (int ret = modifyPhysicalNetwork(netId, interface, permission, ACTION_DEL)) {
+        return ret;
+    }
+    if (int ret = flushRoutes(interface)) {
+        return ret;
+    }
+    if (int ret = clearTetheringRules(interface)) {
+        return ret;
+    }
+    updateTableNamesFile();
+    return 0;
+}
+
+int RouteController::addInterfaceToVirtualNetwork(unsigned netId, const char* interface,
+                                                  bool secure, const UidRanges& uidRanges) {
+    if (int ret = modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_ADD,
+                                       MODIFY_NON_UID_BASED_RULES)) {
+        return ret;
+    }
+    updateTableNamesFile();
+    return 0;
+}
+
+int RouteController::removeInterfaceFromVirtualNetwork(unsigned netId, const char* interface,
+                                                       bool secure, const UidRanges& uidRanges) {
+    if (int ret = modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_DEL,
+                                       MODIFY_NON_UID_BASED_RULES)) {
+        return ret;
+    }
+    if (int ret = flushRoutes(interface)) {
+        return ret;
+    }
+    updateTableNamesFile();
+    return 0;
+}
+
+int RouteController::modifyPhysicalNetworkPermission(unsigned netId, const char* interface,
+                                                     Permission oldPermission,
+                                                     Permission newPermission) {
+    // Add the new rules before deleting the old ones, to avoid race conditions.
+    if (int ret = modifyPhysicalNetwork(netId, interface, newPermission, ACTION_ADD)) {
+        return ret;
+    }
+    return modifyPhysicalNetwork(netId, interface, oldPermission, ACTION_DEL);
+}
+
+int RouteController::addUsersToVirtualNetwork(unsigned netId, const char* interface, bool secure,
+                                              const UidRanges& uidRanges) {
+    return modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_ADD,
+                                !MODIFY_NON_UID_BASED_RULES);
+}
+
+int RouteController::removeUsersFromVirtualNetwork(unsigned netId, const char* interface,
+                                                   bool secure, const UidRanges& uidRanges) {
+    return modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_DEL,
+                                !MODIFY_NON_UID_BASED_RULES);
+}
+
+int RouteController::addInterfaceToDefaultNetwork(const char* interface, Permission permission) {
+    return modifyDefaultNetwork(RTM_NEWRULE, interface, permission);
+}
+
+int RouteController::removeInterfaceFromDefaultNetwork(const char* interface,
+                                                       Permission permission) {
+    return modifyDefaultNetwork(RTM_DELRULE, interface, permission);
+}
+
+int RouteController::addRoute(const char* interface, const char* destination, const char* nexthop,
+                              TableType tableType) {
+    return modifyRoute(RTM_NEWROUTE, interface, destination, nexthop, tableType);
+}
+
+int RouteController::removeRoute(const char* interface, const char* destination,
+                                 const char* nexthop, TableType tableType) {
+    return modifyRoute(RTM_DELROUTE, interface, destination, nexthop, tableType);
+}
+
+int RouteController::enableTethering(const char* inputInterface, const char* outputInterface) {
+    return modifyTetheredNetwork(RTM_NEWRULE, inputInterface, outputInterface);
+}
+
+int RouteController::disableTethering(const char* inputInterface, const char* outputInterface) {
+    return modifyTetheredNetwork(RTM_DELRULE, inputInterface, outputInterface);
+}
+
+int RouteController::addVirtualNetworkFallthrough(unsigned vpnNetId, const char* physicalInterface,
+                                                  Permission permission) {
+    return modifyVpnFallthroughRule(RTM_NEWRULE, vpnNetId, physicalInterface, permission);
+}
+
+int RouteController::removeVirtualNetworkFallthrough(unsigned vpnNetId,
+                                                     const char* physicalInterface,
+                                                     Permission permission) {
+    return modifyVpnFallthroughRule(RTM_DELRULE, vpnNetId, physicalInterface, permission);
+}
diff --git a/netd/server/RouteController.h b/netd/server/RouteController.h
new file mode 100644
index 0000000..0694ea2
--- /dev/null
+++ b/netd/server/RouteController.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_SERVER_ROUTE_CONTROLLER_H
+#define NETD_SERVER_ROUTE_CONTROLLER_H
+
+#include "NetdConstants.h"
+#include "Permission.h"
+
+#include <sys/types.h>
+
+class UidRanges;
+
+class RouteController {
+public:
+    // How the routing table number is determined for route modification requests.
+    enum TableType {
+        INTERFACE,       // Compute the table number based on the interface index.
+        LOCAL_NETWORK,   // A fixed table used for routes to directly-connected clients/peers.
+        LEGACY_NETWORK,  // Use a fixed table that's used to override the default network.
+        LEGACY_SYSTEM,   // A fixed table, only modifiable by system apps; overrides VPNs too.
+    };
+
+    static const int ROUTE_TABLE_OFFSET_FROM_INDEX = 1000;
+
+    static int Init(unsigned localNetId) WARN_UNUSED_RESULT;
+
+    static int addInterfaceToLocalNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT;
+    static int removeInterfaceFromLocalNetwork(unsigned netId,
+                                               const char* interface) WARN_UNUSED_RESULT;
+
+    static int addInterfaceToPhysicalNetwork(unsigned netId, const char* interface,
+                                             Permission permission) WARN_UNUSED_RESULT;
+    static int removeInterfaceFromPhysicalNetwork(unsigned netId, const char* interface,
+                                                  Permission permission) WARN_UNUSED_RESULT;
+
+    static int addInterfaceToVirtualNetwork(unsigned netId, const char* interface, bool secure,
+                                            const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+    static int removeInterfaceFromVirtualNetwork(unsigned netId, const char* interface, bool secure,
+                                                 const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+
+    static int modifyPhysicalNetworkPermission(unsigned netId, const char* interface,
+                                               Permission oldPermission,
+                                               Permission newPermission) WARN_UNUSED_RESULT;
+
+    static int addUsersToVirtualNetwork(unsigned netId, const char* interface, bool secure,
+                                        const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+    static int removeUsersFromVirtualNetwork(unsigned netId, const char* interface, bool secure,
+                                             const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+
+    static int addInterfaceToDefaultNetwork(const char* interface,
+                                            Permission permission) WARN_UNUSED_RESULT;
+    static int removeInterfaceFromDefaultNetwork(const char* interface,
+                                                 Permission permission) WARN_UNUSED_RESULT;
+
+    // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
+    // route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
+    static int addRoute(const char* interface, const char* destination, const char* nexthop,
+                        TableType tableType) WARN_UNUSED_RESULT;
+    static int removeRoute(const char* interface, const char* destination, const char* nexthop,
+                           TableType tableType) WARN_UNUSED_RESULT;
+
+    static int enableTethering(const char* inputInterface,
+                               const char* outputInterface) WARN_UNUSED_RESULT;
+    static int disableTethering(const char* inputInterface,
+                                const char* outputInterface) WARN_UNUSED_RESULT;
+
+    static int addVirtualNetworkFallthrough(unsigned vpnNetId, const char* physicalInterface,
+                                            Permission permission) WARN_UNUSED_RESULT;
+    static int removeVirtualNetworkFallthrough(unsigned vpnNetId, const char* physicalInterface,
+                                               Permission permission) WARN_UNUSED_RESULT;
+};
+
+#endif  // NETD_SERVER_ROUTE_CONTROLLER_H
diff --git a/netd/server/SockDiag.cpp b/netd/server/SockDiag.cpp
new file mode 100644
index 0000000..cd96a26
--- /dev/null
+++ b/netd/server/SockDiag.cpp
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <linux/netlink.h>
+#include <linux/sock_diag.h>
+#include <linux/inet_diag.h>
+
+#define LOG_TAG "Netd"
+
+#include <cutils/log.h>
+
+#include "NetdConstants.h"
+#include "SockDiag.h"
+
+#include <chrono>
+
+#ifndef SOCK_DESTROY
+#define SOCK_DESTROY 21
+#endif
+
+namespace {
+
+struct AddrinfoDeleter {
+  void operator()(addrinfo *a) { if (a) freeaddrinfo(a); }
+};
+
+typedef std::unique_ptr<addrinfo, AddrinfoDeleter> ScopedAddrinfo;
+
+int checkError(int fd) {
+    struct {
+        nlmsghdr h;
+        nlmsgerr err;
+    } __attribute__((__packed__)) ack;
+    ssize_t bytesread = recv(fd, &ack, sizeof(ack), MSG_DONTWAIT | MSG_PEEK);
+    if (bytesread == -1) {
+       // Read failed (error), or nothing to read (good).
+       return (errno == EAGAIN) ? 0 : -errno;
+    } else if (bytesread == (ssize_t) sizeof(ack) && ack.h.nlmsg_type == NLMSG_ERROR) {
+        // We got an error. Consume it.
+        recv(fd, &ack, sizeof(ack), 0);
+        return ack.err.error;
+    } else {
+        // The kernel replied with something. Leave it to the caller.
+        return 0;
+    }
+}
+
+}  // namespace
+
+bool SockDiag::open() {
+    if (hasSocks()) {
+        return false;
+    }
+
+    mSock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_INET_DIAG);
+    mWriteSock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_INET_DIAG);
+    if (!hasSocks()) {
+        closeSocks();
+        return false;
+    }
+
+    sockaddr_nl nl = { .nl_family = AF_NETLINK };
+    if ((connect(mSock, reinterpret_cast<sockaddr *>(&nl), sizeof(nl)) == -1) ||
+        (connect(mWriteSock, reinterpret_cast<sockaddr *>(&nl), sizeof(nl)) == -1)) {
+        closeSocks();
+        return false;
+    }
+
+    return true;
+}
+
+int SockDiag::sendDumpRequest(uint8_t proto, uint8_t family, const char *addrstr) {
+    addrinfo hints = { .ai_flags = AI_NUMERICHOST };
+    addrinfo *res;
+    in6_addr mapped = { .s6_addr32 = { 0, 0, htonl(0xffff), 0 } };
+    int ret;
+
+    // TODO: refactor the netlink parsing code out of system/core, bring it into netd, and stop
+    // doing string conversions when they're not necessary.
+    if ((ret = getaddrinfo(addrstr, nullptr, &hints, &res)) != 0) {
+        return -EINVAL;
+    }
+
+    // So we don't have to call freeaddrinfo on every failure path.
+    ScopedAddrinfo resP(res);
+
+    void *addr;
+    uint8_t addrlen;
+    if (res->ai_family == AF_INET && family == AF_INET) {
+        in_addr& ina = reinterpret_cast<sockaddr_in*>(res->ai_addr)->sin_addr;
+        addr = &ina;
+        addrlen = sizeof(ina);
+    } else if (res->ai_family == AF_INET && family == AF_INET6) {
+        in_addr& ina = reinterpret_cast<sockaddr_in*>(res->ai_addr)->sin_addr;
+        mapped.s6_addr32[3] = ina.s_addr;
+        addr = &mapped;
+        addrlen = sizeof(mapped);
+    } else if (res->ai_family == AF_INET6 && family == AF_INET6) {
+        in6_addr& in6a = reinterpret_cast<sockaddr_in6*>(res->ai_addr)->sin6_addr;
+        addr = &in6a;
+        addrlen = sizeof(in6a);
+    } else {
+        return -EAFNOSUPPORT;
+    }
+
+    uint8_t prefixlen = addrlen * 8;
+    uint8_t yesjump = sizeof(inet_diag_bc_op) + sizeof(inet_diag_hostcond) + addrlen;
+    uint8_t nojump = yesjump + 4;
+    uint32_t states = ~(1 << TCP_TIME_WAIT);
+
+    struct {
+        nlmsghdr nlh;
+        inet_diag_req_v2 req;
+        nlattr nla;
+        inet_diag_bc_op op;
+        inet_diag_hostcond cond;
+    } __attribute__((__packed__)) request = {
+        .nlh = {
+            .nlmsg_type = SOCK_DIAG_BY_FAMILY,
+            .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
+        },
+        .req = {
+            .sdiag_family = family,
+            .sdiag_protocol = proto,
+            .idiag_states = states,
+        },
+        .nla = {
+            .nla_type = INET_DIAG_REQ_BYTECODE,
+        },
+        .op = {
+            INET_DIAG_BC_S_COND,
+            yesjump,
+            nojump,
+        },
+        .cond = {
+            family,
+            prefixlen,
+            -1,
+            {}
+        },
+    };
+
+    request.nlh.nlmsg_len = sizeof(request) + addrlen;
+    request.nla.nla_len = sizeof(request.nla) + sizeof(request.op) + sizeof(request.cond) + addrlen;
+
+    struct iovec iov[] = {
+        { &request, sizeof(request) },
+        { addr, addrlen },
+    };
+
+    if (writev(mSock, iov, ARRAY_SIZE(iov)) != (int) request.nlh.nlmsg_len) {
+        return -errno;
+    }
+
+    return checkError(mSock);
+}
+
+int SockDiag::readDiagMsg(uint8_t proto, const SockDiag::DumpCallback& callback) {
+    char buf[kBufferSize];
+
+    ssize_t bytesread;
+    do {
+        bytesread = read(mSock, buf, sizeof(buf));
+
+        if (bytesread < 0) {
+            return -errno;
+        }
+
+        uint32_t len = bytesread;
+        for (nlmsghdr *nlh = reinterpret_cast<nlmsghdr *>(buf);
+             NLMSG_OK(nlh, len);
+             nlh = NLMSG_NEXT(nlh, len)) {
+            switch (nlh->nlmsg_type) {
+              case NLMSG_DONE:
+                callback(proto, NULL);
+                return 0;
+              case NLMSG_ERROR: {
+                nlmsgerr *err = reinterpret_cast<nlmsgerr *>(NLMSG_DATA(nlh));
+                return err->error;
+              }
+              default:
+                inet_diag_msg *msg = reinterpret_cast<inet_diag_msg *>(NLMSG_DATA(nlh));
+                callback(proto, msg);
+            }
+        }
+    } while (bytesread > 0);
+
+    return 0;
+}
+
+int SockDiag::sockDestroy(uint8_t proto, const inet_diag_msg *msg) {
+    if (msg == nullptr) {
+       return 0;
+    }
+
+    DestroyRequest request = {
+        .nlh = {
+            .nlmsg_type = SOCK_DESTROY,
+            .nlmsg_flags = NLM_F_REQUEST,
+        },
+        .req = {
+            .sdiag_family = msg->idiag_family,
+            .sdiag_protocol = proto,
+            .idiag_states = (uint32_t) (1 << msg->idiag_state),
+            .id = msg->id,
+        },
+    };
+    request.nlh.nlmsg_len = sizeof(request);
+
+    if (write(mWriteSock, &request, sizeof(request)) < (ssize_t) sizeof(request)) {
+        return -errno;
+    }
+
+    int ret = checkError(mWriteSock);
+    if (!ret) mSocketsDestroyed++;
+    return ret;
+}
+
+int SockDiag::destroySockets(uint8_t proto, int family, const char *addrstr) {
+    if (!hasSocks()) {
+        return -EBADFD;
+    }
+
+    if (int ret = sendDumpRequest(proto, family, addrstr)) {
+        return ret;
+    }
+
+    auto destroy = [this] (uint8_t proto, const inet_diag_msg *msg) {
+        return this->sockDestroy(proto, msg);
+    };
+
+    return readDiagMsg(proto, destroy);
+}
+
+int SockDiag::destroySockets(const char *addrstr) {
+    using ms = std::chrono::duration<float, std::ratio<1, 1000>>;
+
+    mSocketsDestroyed = 0;
+    const auto start = std::chrono::steady_clock::now();
+    if (!strchr(addrstr, ':')) {
+        if (int ret = destroySockets(IPPROTO_TCP, AF_INET, addrstr)) {
+            ALOGE("Failed to destroy IPv4 sockets on %s: %s", addrstr, strerror(-ret));
+            return ret;
+        }
+    }
+    if (int ret = destroySockets(IPPROTO_TCP, AF_INET6, addrstr)) {
+        ALOGE("Failed to destroy IPv6 sockets on %s: %s", addrstr, strerror(-ret));
+        return ret;
+    }
+    auto elapsed = std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start);
+
+    if (mSocketsDestroyed > 0) {
+        ALOGI("Destroyed %d sockets on %s in %.1f ms", mSocketsDestroyed, addrstr, elapsed.count());
+    }
+
+    return mSocketsDestroyed;
+}
diff --git a/netd/server/SockDiag.h b/netd/server/SockDiag.h
new file mode 100644
index 0000000..ccd54bf
--- /dev/null
+++ b/netd/server/SockDiag.h
@@ -0,0 +1,37 @@
+#include <functional>
+
+#include <linux/netlink.h>
+#include <linux/sock_diag.h>
+#include <linux/inet_diag.h>
+
+struct inet_diag_msg;
+class SockDiagTest;
+
+class SockDiag {
+
+  public:
+    static const int kBufferSize = 4096;
+    typedef std::function<int(uint8_t proto, const inet_diag_msg *)> DumpCallback;
+
+    struct DestroyRequest {
+        nlmsghdr nlh;
+        inet_diag_req_v2 req;
+    } __attribute__((__packed__));
+
+    SockDiag() : mSock(-1), mWriteSock(-1), mSocketsDestroyed(0) {}
+    bool open();
+    virtual ~SockDiag() { closeSocks(); }
+
+    int sendDumpRequest(uint8_t proto, uint8_t family, const char *addrstr);
+    int readDiagMsg(uint8_t proto, const DumpCallback& callback);
+    int sockDestroy(uint8_t proto, const inet_diag_msg *);
+    int destroySockets(const char *addrstr);
+
+  private:
+    int mSock;
+    int mWriteSock;
+    int mSocketsDestroyed;
+    int destroySockets(uint8_t proto, int family, const char *addrstr);
+    bool hasSocks() { return mSock != -1 && mWriteSock != -1; }
+    void closeSocks() { close(mSock); close(mWriteSock); mSock = mWriteSock = -1; }
+};
diff --git a/netd/server/SoftapController.cpp b/netd/server/SoftapController.cpp
new file mode 100644
index 0000000..ce92820
--- /dev/null
+++ b/netd/server/SoftapController.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2008 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 <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <linux/wireless.h>
+
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#define LOG_TAG "SoftapController"
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <cutils/log.h>
+#include <netutils/ifc.h>
+#include <private/android_filesystem_config.h>
+#include "wifi.h"
+#include "ResponseCode.h"
+
+#include "SoftapController.h"
+
+using android::base::StringPrintf;
+using android::base::WriteStringToFile;
+
+static const char HOSTAPD_CONF_FILE[]    = "/data/misc/wifi/hostapd.conf";
+static const char HOSTAPD_BIN_FILE[]    = "/system/bin/hostapd";
+
+SoftapController::SoftapController()
+    : mPid(0) {}
+
+SoftapController::~SoftapController() {
+}
+
+int SoftapController::startSoftap() {
+    pid_t pid = 1;
+
+    if (mPid) {
+        ALOGE("SoftAP is already running");
+        return ResponseCode::SoftapStatusResult;
+    }
+
+    if (ensure_entropy_file_exists() < 0) {
+        ALOGE("Wi-Fi entropy file was not created");
+    }
+
+    if ((pid = fork()) < 0) {
+        ALOGE("fork failed (%s)", strerror(errno));
+        return ResponseCode::ServiceStartFailed;
+    }
+
+    if (!pid) {
+        ensure_entropy_file_exists();
+        if (execl(HOSTAPD_BIN_FILE, HOSTAPD_BIN_FILE,
+                  "-e", WIFI_ENTROPY_FILE,
+                  HOSTAPD_CONF_FILE, (char *) NULL)) {
+            ALOGE("execl failed (%s)", strerror(errno));
+        }
+        ALOGE("SoftAP failed to start");
+        return ResponseCode::ServiceStartFailed;
+    } else {
+        mPid = pid;
+        ALOGD("SoftAP started successfully");
+        usleep(AP_BSS_START_DELAY);
+    }
+    return ResponseCode::SoftapStatusResult;
+}
+
+int SoftapController::stopSoftap() {
+
+    if (mPid == 0) {
+        ALOGE("SoftAP is not running");
+        return ResponseCode::SoftapStatusResult;
+    }
+
+    ALOGD("Stopping the SoftAP service...");
+    kill(mPid, SIGTERM);
+    waitpid(mPid, NULL, 0);
+
+    mPid = 0;
+    ALOGD("SoftAP stopped successfully");
+    usleep(AP_BSS_STOP_DELAY);
+    return ResponseCode::SoftapStatusResult;
+}
+
+bool SoftapController::isSoftapStarted() {
+    return (mPid != 0);
+}
+
+/*
+ * Arguments:
+ *  argv[2] - wlan interface
+ *  argv[3] - SSID
+ *  argv[4] - Broadcast/Hidden
+ *  argv[5] - Channel
+ *  argv[6] - Security
+ *  argv[7] - Key
+ */
+int SoftapController::setSoftap(int argc, char *argv[]) {
+    int hidden = 0;
+    int channel = AP_CHANNEL_DEFAULT;
+
+    if (argc < 5) {
+        ALOGE("Softap set is missing arguments. Please use:");
+        ALOGE("softap <wlan iface> <SSID> <hidden/broadcast> <channel> <wpa2?-psk|open> <passphrase>");
+        return ResponseCode::CommandSyntaxError;
+    }
+
+    if (!strcasecmp(argv[4], "hidden"))
+        hidden = 1;
+
+    if (argc >= 5) {
+        channel = atoi(argv[5]);
+        if (channel <= 0)
+            channel = AP_CHANNEL_DEFAULT;
+    }
+
+    std::string wbuf(StringPrintf("interface=%s\n"
+            "driver=nl80211\n"
+            "ctrl_interface=/data/misc/wifi/hostapd\n"
+            "ssid=%s\n"
+            "channel=%d\n"
+            "ieee80211n=1\n"
+            "hw_mode=%c\n"
+            "ignore_broadcast_ssid=%d\n"
+            "wowlan_triggers=any\n",
+            argv[2], argv[3], channel, (channel <= 14) ? 'g' : 'a', hidden));
+
+    std::string fbuf;
+    if (argc > 7) {
+        char psk_str[2*SHA256_DIGEST_LENGTH+1];
+        if (!strcmp(argv[6], "wpa-psk")) {
+            if (!generatePsk(argv[3], argv[7], psk_str)) {
+                return ResponseCode::OperationFailed;
+            }
+            fbuf = StringPrintf("%swpa=3\nwpa_pairwise=TKIP CCMP\nwpa_psk=%s\n", wbuf.c_str(), psk_str);
+        } else if (!strcmp(argv[6], "wpa2-psk")) {
+            if (!generatePsk(argv[3], argv[7], psk_str)) {
+                return ResponseCode::OperationFailed;
+            }
+            fbuf = StringPrintf("%swpa=2\nrsn_pairwise=CCMP\nwpa_psk=%s\n", wbuf.c_str(), psk_str);
+        } else if (!strcmp(argv[6], "open")) {
+            fbuf = wbuf;
+        }
+    } else if (argc > 6) {
+        if (!strcmp(argv[6], "open")) {
+            fbuf = wbuf;
+        }
+    } else {
+        fbuf = wbuf;
+    }
+
+    if (!WriteStringToFile(fbuf, HOSTAPD_CONF_FILE, 0660, AID_SYSTEM, AID_WIFI)) {
+        ALOGE("Cannot write to \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
+        return ResponseCode::OperationFailed;
+    }
+    return ResponseCode::SoftapStatusResult;
+}
+
+/*
+ * Arguments:
+ *	argv[2] - interface name
+ *	argv[3] - AP or P2P or STA
+ */
+int SoftapController::fwReloadSoftap(int argc, char *argv[])
+{
+    char *fwpath = NULL;
+
+    if (argc < 4) {
+        ALOGE("SoftAP fwreload is missing arguments. Please use: softap <wlan iface> <AP|P2P|STA>");
+        return ResponseCode::CommandSyntaxError;
+    }
+
+    if (strcmp(argv[3], "AP") == 0) {
+        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_AP);
+    } else if (strcmp(argv[3], "P2P") == 0) {
+        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_P2P);
+    } else if (strcmp(argv[3], "STA") == 0) {
+        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_STA);
+    }
+    if (!fwpath)
+        return ResponseCode::CommandParameterError;
+    if (wifi_change_fw_path((const char *)fwpath)) {
+        ALOGE("Softap fwReload failed");
+        return ResponseCode::OperationFailed;
+    }
+    else {
+        ALOGD("Softap fwReload - Ok");
+    }
+    return ResponseCode::SoftapStatusResult;
+}
+
+bool SoftapController::generatePsk(char *ssid, char *passphrase, char *psk_str) {
+    unsigned char psk[SHA256_DIGEST_LENGTH];
+
+    // Use the PKCS#5 PBKDF2 with 4096 iterations
+    if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, strlen(passphrase),
+                               reinterpret_cast<const unsigned char *>(ssid),
+                               strlen(ssid), 4096, SHA256_DIGEST_LENGTH,
+                               psk) != 1) {
+        ALOGE("Cannot generate PSK using PKCS#5 PBKDF2");
+        return false;
+    }
+
+    for (int j=0; j < SHA256_DIGEST_LENGTH; j++) {
+        sprintf(&psk_str[j*2], "%02x", psk[j]);
+    }
+
+    return true;
+}
diff --git a/netd/server/SoftapController.h b/netd/server/SoftapController.h
new file mode 100644
index 0000000..68025e2
--- /dev/null
+++ b/netd/server/SoftapController.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _SOFTAP_CONTROLLER_H
+#define _SOFTAP_CONTROLLER_H
+
+#include <linux/in.h>
+#include <net/if.h>
+
+#define SOFTAP_MAX_BUFFER_SIZE	4096
+#define AP_BSS_START_DELAY	200000
+#define AP_BSS_STOP_DELAY	500000
+#define AP_SET_CFG_DELAY	500000
+#define AP_DRIVER_START_DELAY	800000
+#define AP_CHANNEL_DEFAULT	6
+
+class SoftapController {
+public:
+    SoftapController();
+    virtual ~SoftapController();
+
+    int startSoftap();
+    int stopSoftap();
+    bool isSoftapStarted();
+    int setSoftap(int argc, char *argv[]);
+    int fwReloadSoftap(int argc, char *argv[]);
+private:
+    pid_t mPid;
+    bool generatePsk(char *ssid, char *passphrase, char *psk);
+};
+
+#endif
diff --git a/netd/server/StrictController.cpp b/netd/server/StrictController.cpp
new file mode 100644
index 0000000..a04124d
--- /dev/null
+++ b/netd/server/StrictController.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2014 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define LOG_TAG "StrictController"
+#define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+
+#include "ConnmarkFlags.h"
+#include "NetdConstants.h"
+#include "StrictController.h"
+
+const char* StrictController::LOCAL_OUTPUT = "st_OUTPUT";
+const char* StrictController::LOCAL_CLEAR_DETECT = "st_clear_detect";
+const char* StrictController::LOCAL_CLEAR_CAUGHT = "st_clear_caught";
+const char* StrictController::LOCAL_PENALTY_LOG = "st_penalty_log";
+const char* StrictController::LOCAL_PENALTY_REJECT = "st_penalty_reject";
+
+StrictController::StrictController(void) {
+}
+
+int StrictController::enableStrict(void) {
+    char connmarkFlagAccept[16];
+    char connmarkFlagReject[16];
+    char connmarkFlagTestAccept[32];
+    char connmarkFlagTestReject[32];
+    sprintf(connmarkFlagAccept, "0x%x", ConnmarkFlags::STRICT_RESOLVED_ACCEPT);
+    sprintf(connmarkFlagReject, "0x%x", ConnmarkFlags::STRICT_RESOLVED_REJECT);
+    sprintf(connmarkFlagTestAccept, "0x%x/0x%x",
+            ConnmarkFlags::STRICT_RESOLVED_ACCEPT,
+            ConnmarkFlags::STRICT_RESOLVED_ACCEPT);
+    sprintf(connmarkFlagTestReject, "0x%x/0x%x",
+            ConnmarkFlags::STRICT_RESOLVED_REJECT,
+            ConnmarkFlags::STRICT_RESOLVED_REJECT);
+
+    int res = 0;
+
+    disableStrict();
+
+    // Chain triggered when cleartext socket detected and penalty is log
+    res |= execIptables(V4V6, "-N", LOCAL_PENALTY_LOG, NULL);
+    res |= execIptables(V4V6, "-A", LOCAL_PENALTY_LOG,
+            "-j", "CONNMARK", "--or-mark", connmarkFlagAccept, NULL);
+    res |= execIptables(V4V6, "-A", LOCAL_PENALTY_LOG,
+            "-j", "NFLOG", "--nflog-group", "0", NULL);
+
+    // Chain triggered when cleartext socket detected and penalty is reject
+    res |= execIptables(V4V6, "-N", LOCAL_PENALTY_REJECT, NULL);
+    res |= execIptables(V4V6, "-A", LOCAL_PENALTY_REJECT,
+            "-j", "CONNMARK", "--or-mark", connmarkFlagReject, NULL);
+    res |= execIptables(V4V6, "-A", LOCAL_PENALTY_REJECT,
+            "-j", "NFLOG", "--nflog-group", "0", NULL);
+    res |= execIptables(V4V6, "-A", LOCAL_PENALTY_REJECT,
+            "-j", "REJECT", NULL);
+
+    // Create chain to detect non-TLS traffic. We use a high-order
+    // mark bit to keep track of connections that we've already resolved.
+    res |= execIptables(V4V6, "-N", LOCAL_CLEAR_DETECT, NULL);
+    res |= execIptables(V4V6, "-N", LOCAL_CLEAR_CAUGHT, NULL);
+
+    // Quickly skip connections that we've already resolved
+    res |= execIptables(V4V6, "-A", LOCAL_CLEAR_DETECT,
+            "-m", "connmark", "--mark", connmarkFlagTestReject,
+            "-j", "REJECT", NULL);
+    res |= execIptables(V4V6, "-A", LOCAL_CLEAR_DETECT,
+            "-m", "connmark", "--mark", connmarkFlagTestAccept,
+            "-j", "RETURN", NULL);
+
+    // Look for IPv4 TCP/UDP connections with TLS/DTLS header
+    res |= execIptables(V4, "-A", LOCAL_CLEAR_DETECT, "-p", "tcp",
+            "-m", "u32", "--u32", "0>>22&0x3C@ 12>>26&0x3C@ 0&0xFFFF0000=0x16030000 &&"
+                                  "0>>22&0x3C@ 12>>26&0x3C@ 4&0x00FF0000=0x00010000",
+            "-j", "CONNMARK", "--or-mark", connmarkFlagAccept, NULL);
+    res |= execIptables(V4, "-A", LOCAL_CLEAR_DETECT, "-p", "udp",
+            "-m", "u32", "--u32", "0>>22&0x3C@ 8&0xFFFF0000=0x16FE0000 &&"
+                                  "0>>22&0x3C@ 20&0x00FF0000=0x00010000",
+            "-j", "CONNMARK", "--or-mark", connmarkFlagAccept, NULL);
+
+    // Look for IPv6 TCP/UDP connections with TLS/DTLS header.  The IPv6 header
+    // doesn't have an IHL field to shift with, so we have to manually add in
+    // the 40-byte offset at every step.
+    res |= execIptables(V6, "-A", LOCAL_CLEAR_DETECT, "-p", "tcp",
+            "-m", "u32", "--u32", "52>>26&0x3C@ 40&0xFFFF0000=0x16030000 &&"
+                                  "52>>26&0x3C@ 44&0x00FF0000=0x00010000",
+            "-j", "CONNMARK", "--or-mark", connmarkFlagAccept, NULL);
+    res |= execIptables(V6, "-A", LOCAL_CLEAR_DETECT, "-p", "udp",
+            "-m", "u32", "--u32", "48&0xFFFF0000=0x16FE0000 &&"
+                                  "60&0x00FF0000=0x00010000",
+            "-j", "CONNMARK", "--or-mark", connmarkFlagAccept, NULL);
+
+    // Skip newly classified connections from above
+    res |= execIptables(V4V6, "-A", LOCAL_CLEAR_DETECT,
+            "-m", "connmark", "--mark", connmarkFlagTestAccept,
+            "-j", "RETURN", NULL);
+
+    // Handle TCP/UDP payloads that didn't match TLS/DTLS filters above,
+    // which means we've probably found cleartext data.  The TCP variant
+    // depends on u32 returning false when we try reading into the message
+    // body to ignore empty ACK packets.
+    res |= execIptables(V4, "-A", LOCAL_CLEAR_DETECT, "-p", "tcp",
+            "-m", "state", "--state", "ESTABLISHED",
+            "-m", "u32", "--u32", "0>>22&0x3C@ 12>>26&0x3C@ 0&0x0=0x0",
+            "-j", LOCAL_CLEAR_CAUGHT, NULL);
+    res |= execIptables(V6, "-A", LOCAL_CLEAR_DETECT, "-p", "tcp",
+            "-m", "state", "--state", "ESTABLISHED",
+            "-m", "u32", "--u32", "52>>26&0x3C@ 40&0x0=0x0",
+            "-j", LOCAL_CLEAR_CAUGHT, NULL);
+
+    res |= execIptables(V4V6, "-A", LOCAL_CLEAR_DETECT, "-p", "udp",
+            "-j", LOCAL_CLEAR_CAUGHT, NULL);
+
+    return res;
+}
+
+int StrictController::disableStrict(void) {
+    int res = 0;
+
+    // Flush any existing rules
+    res |= execIptables(V4V6, "-F", LOCAL_OUTPUT, NULL);
+
+    res |= execIptables(V4V6, "-F", LOCAL_PENALTY_LOG, NULL);
+    res |= execIptables(V4V6, "-F", LOCAL_PENALTY_REJECT, NULL);
+    res |= execIptables(V4V6, "-F", LOCAL_CLEAR_CAUGHT, NULL);
+    res |= execIptables(V4V6, "-F", LOCAL_CLEAR_DETECT, NULL);
+
+    res |= execIptables(V4V6, "-X", LOCAL_PENALTY_LOG, NULL);
+    res |= execIptables(V4V6, "-X", LOCAL_PENALTY_REJECT, NULL);
+    res |= execIptables(V4V6, "-X", LOCAL_CLEAR_CAUGHT, NULL);
+    res |= execIptables(V4V6, "-X", LOCAL_CLEAR_DETECT, NULL);
+
+    return res;
+}
+
+int StrictController::setUidCleartextPenalty(uid_t uid, StrictPenalty penalty) {
+    char uidStr[16];
+    sprintf(uidStr, "%d", uid);
+
+    int res = 0;
+    if (penalty == ACCEPT) {
+        // Clean up any old rules
+        execIptables(V4V6, "-D", LOCAL_OUTPUT,
+                "-m", "owner", "--uid-owner", uidStr,
+                "-j", LOCAL_CLEAR_DETECT, NULL);
+        execIptables(V4V6, "-D", LOCAL_CLEAR_CAUGHT,
+                "-m", "owner", "--uid-owner", uidStr,
+                "-j", LOCAL_PENALTY_LOG, NULL);
+        execIptables(V4V6, "-D", LOCAL_CLEAR_CAUGHT,
+                "-m", "owner", "--uid-owner", uidStr,
+                "-j", LOCAL_PENALTY_REJECT, NULL);
+
+    } else {
+        // Always take a detour to investigate this UID
+        res |= execIptables(V4V6, "-I", LOCAL_OUTPUT,
+                "-m", "owner", "--uid-owner", uidStr,
+                "-j", LOCAL_CLEAR_DETECT, NULL);
+
+        if (penalty == LOG) {
+            res |= execIptables(V4V6, "-I", LOCAL_CLEAR_CAUGHT,
+                    "-m", "owner", "--uid-owner", uidStr,
+                    "-j", LOCAL_PENALTY_LOG, NULL);
+        } else if (penalty == REJECT) {
+            res |= execIptables(V4V6, "-I", LOCAL_CLEAR_CAUGHT,
+                    "-m", "owner", "--uid-owner", uidStr,
+                    "-j", LOCAL_PENALTY_REJECT, NULL);
+        }
+    }
+
+    return res;
+}
diff --git a/netd/server/StrictController.h b/netd/server/StrictController.h
new file mode 100644
index 0000000..52a6779
--- /dev/null
+++ b/netd/server/StrictController.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef _STRICT_CONTROLLER_H
+#define _STRICT_CONTROLLER_H
+
+#include <string>
+
+enum StrictPenalty { INVALID, ACCEPT, LOG, REJECT };
+
+/*
+ * Help apps catch unwanted low-level networking behavior, like
+ * connections not wrapped in TLS.
+ */
+class StrictController {
+public:
+    StrictController();
+
+    int enableStrict(void);
+    int disableStrict(void);
+
+    int setUidCleartextPenalty(uid_t, StrictPenalty);
+
+    static const char* LOCAL_OUTPUT;
+    static const char* LOCAL_CLEAR_DETECT;
+    static const char* LOCAL_CLEAR_CAUGHT;
+    static const char* LOCAL_PENALTY_LOG;
+    static const char* LOCAL_PENALTY_REJECT;
+};
+
+#endif
diff --git a/netd/server/TetherController.cpp b/netd/server/TetherController.cpp
new file mode 100644
index 0000000..88baa31
--- /dev/null
+++ b/netd/server/TetherController.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2008 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 <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define LOG_TAG "TetherController"
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include "Fwmark.h"
+#include "NetdConstants.h"
+#include "Permission.h"
+#include "TetherController.h"
+
+namespace {
+
+static const char BP_TOOLS_MODE[] = "bp-tools";
+static const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
+static const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
+
+bool writeToFile(const char* filename, const char* value) {
+    int fd = open(filename, O_WRONLY);
+    if (fd < 0) {
+        ALOGE("Failed to open %s: %s", filename, strerror(errno));
+        return false;
+    }
+
+    const ssize_t len = strlen(value);
+    if (write(fd, value, len) != len) {
+        ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno));
+        close(fd);
+        return false;
+    }
+    close(fd);
+    return true;
+}
+
+bool inBpToolsMode() {
+    // In BP tools mode, do not disable IP forwarding
+    char bootmode[PROPERTY_VALUE_MAX] = {0};
+    property_get("ro.bootmode", bootmode, "unknown");
+    return !strcmp(BP_TOOLS_MODE, bootmode);
+}
+
+}  // namespace
+
+TetherController::TetherController() {
+    mInterfaces = new InterfaceCollection();
+    mDnsNetId = 0;
+    mDnsForwarders = new NetAddressCollection();
+    mDaemonFd = -1;
+    mDaemonPid = 0;
+    if (inBpToolsMode()) {
+        enableForwarding(BP_TOOLS_MODE);
+    } else {
+        setIpFwdEnabled();
+    }
+}
+
+TetherController::~TetherController() {
+    InterfaceCollection::iterator it;
+
+    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
+        free(*it);
+    }
+    mInterfaces->clear();
+
+    mDnsForwarders->clear();
+    mForwardingRequests.clear();
+}
+
+bool TetherController::setIpFwdEnabled() {
+    bool success = true;
+    const char* value = mForwardingRequests.empty() ? "0" : "1";
+    ALOGD("Setting IP forward enable = %s", value);
+    success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value);
+    success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value);
+    return success;
+}
+
+bool TetherController::enableForwarding(const char* requester) {
+    // Don't return an error if this requester already requested forwarding. Only return errors for
+    // things that the caller caller needs to care about, such as "couldn't write to the file to
+    // enable forwarding".
+    mForwardingRequests.insert(requester);
+    return setIpFwdEnabled();
+}
+
+bool TetherController::disableForwarding(const char* requester) {
+    mForwardingRequests.erase(requester);
+    return setIpFwdEnabled();
+}
+
+size_t TetherController::forwardingRequestCount() {
+    return mForwardingRequests.size();
+}
+
+#define TETHER_START_CONST_ARG        8
+
+int TetherController::startTethering(int num_addrs, struct in_addr* addrs) {
+    if (mDaemonPid != 0) {
+        ALOGE("Tethering already started");
+        errno = EBUSY;
+        return -1;
+    }
+
+    ALOGD("Starting tethering services");
+
+    pid_t pid;
+    int pipefd[2];
+
+    if (pipe(pipefd) < 0) {
+        ALOGE("pipe failed (%s)", strerror(errno));
+        return -1;
+    }
+
+    /*
+     * TODO: Create a monitoring thread to handle and restart
+     * the daemon if it exits prematurely
+     */
+    if ((pid = fork()) < 0) {
+        ALOGE("fork failed (%s)", strerror(errno));
+        close(pipefd[0]);
+        close(pipefd[1]);
+        return -1;
+    }
+
+    if (!pid) {
+        close(pipefd[1]);
+        if (pipefd[0] != STDIN_FILENO) {
+            if (dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) {
+                ALOGE("dup2 failed (%s)", strerror(errno));
+                return -1;
+            }
+            close(pipefd[0]);
+        }
+
+        int num_processed_args = TETHER_START_CONST_ARG + (num_addrs/2) + 1;
+        char **args = (char **)malloc(sizeof(char *) * num_processed_args);
+        args[num_processed_args - 1] = NULL;
+        args[0] = (char *)"/system/bin/dnsmasq";
+        args[1] = (char *)"--keep-in-foreground";
+        args[2] = (char *)"--no-resolv";
+        args[3] = (char *)"--no-poll";
+        args[4] = (char *)"--dhcp-authoritative";
+        // TODO: pipe through metered status from ConnService
+        args[5] = (char *)"--dhcp-option-force=43,ANDROID_METERED";
+        args[6] = (char *)"--pid-file";
+        args[7] = (char *)"";
+
+        int nextArg = TETHER_START_CONST_ARG;
+        for (int addrIndex=0; addrIndex < num_addrs;) {
+            char *start = strdup(inet_ntoa(addrs[addrIndex++]));
+            char *end = strdup(inet_ntoa(addrs[addrIndex++]));
+            asprintf(&(args[nextArg++]),"--dhcp-range=%s,%s,1h", start, end);
+            free(start);
+            free(end);
+        }
+
+        if (execv(args[0], args)) {
+            ALOGE("execl failed (%s)", strerror(errno));
+        }
+        ALOGE("Should never get here!");
+        _exit(-1);
+    } else {
+        close(pipefd[0]);
+        mDaemonPid = pid;
+        mDaemonFd = pipefd[1];
+        applyDnsInterfaces();
+        ALOGD("Tethering services running");
+    }
+
+    return 0;
+}
+
+int TetherController::stopTethering() {
+
+    if (mDaemonPid == 0) {
+        ALOGE("Tethering already stopped");
+        return 0;
+    }
+
+    ALOGD("Stopping tethering services");
+
+    kill(mDaemonPid, SIGTERM);
+    waitpid(mDaemonPid, NULL, 0);
+    mDaemonPid = 0;
+    close(mDaemonFd);
+    mDaemonFd = -1;
+    ALOGD("Tethering services stopped");
+    return 0;
+}
+
+bool TetherController::isTetheringStarted() {
+    return (mDaemonPid == 0 ? false : true);
+}
+
+#define MAX_CMD_SIZE 1024
+
+int TetherController::setDnsForwarders(unsigned netId, char **servers, int numServers) {
+    int i;
+    char daemonCmd[MAX_CMD_SIZE];
+
+    Fwmark fwmark;
+    fwmark.netId = netId;
+    fwmark.explicitlySelected = true;
+    fwmark.protectedFromVpn = true;
+    fwmark.permission = PERMISSION_SYSTEM;
+
+    snprintf(daemonCmd, sizeof(daemonCmd), "update_dns:0x%x", fwmark.intValue);
+    int cmdLen = strlen(daemonCmd);
+
+    mDnsForwarders->clear();
+    for (i = 0; i < numServers; i++) {
+        ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
+
+        struct in_addr a;
+
+        if (!inet_aton(servers[i], &a)) {
+            ALOGE("Failed to parse DNS server '%s'", servers[i]);
+            mDnsForwarders->clear();
+            return -1;
+        }
+
+        cmdLen += (strlen(servers[i]) + 1);
+        if (cmdLen + 1 >= MAX_CMD_SIZE) {
+            ALOGD("Too many DNS servers listed");
+            break;
+        }
+
+        strcat(daemonCmd, ":");
+        strcat(daemonCmd, servers[i]);
+        mDnsForwarders->push_back(a);
+    }
+
+    mDnsNetId = netId;
+    if (mDaemonFd != -1) {
+        ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
+        if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
+            ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
+            mDnsForwarders->clear();
+            return -1;
+        }
+    }
+    return 0;
+}
+
+unsigned TetherController::getDnsNetId() {
+    return mDnsNetId;
+}
+
+NetAddressCollection *TetherController::getDnsForwarders() {
+    return mDnsForwarders;
+}
+
+int TetherController::applyDnsInterfaces() {
+    char daemonCmd[MAX_CMD_SIZE];
+
+    strcpy(daemonCmd, "update_ifaces");
+    int cmdLen = strlen(daemonCmd);
+    InterfaceCollection::iterator it;
+    bool haveInterfaces = false;
+
+    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
+        cmdLen += (strlen(*it) + 1);
+        if (cmdLen + 1 >= MAX_CMD_SIZE) {
+            ALOGD("Too many DNS ifaces listed");
+            break;
+        }
+
+        strcat(daemonCmd, ":");
+        strcat(daemonCmd, *it);
+        haveInterfaces = true;
+    }
+
+    if ((mDaemonFd != -1) && haveInterfaces) {
+        ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
+        if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
+            ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
+            return -1;
+        }
+    }
+    return 0;
+}
+
+int TetherController::tetherInterface(const char *interface) {
+    ALOGD("tetherInterface(%s)", interface);
+    if (!isIfaceName(interface)) {
+        errno = ENOENT;
+        return -1;
+    }
+    mInterfaces->push_back(strdup(interface));
+
+    if (applyDnsInterfaces()) {
+        InterfaceCollection::iterator it;
+        for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
+            if (!strcmp(interface, *it)) {
+                free(*it);
+                mInterfaces->erase(it);
+                break;
+            }
+        }
+        return -1;
+    } else {
+        return 0;
+    }
+}
+
+int TetherController::untetherInterface(const char *interface) {
+    InterfaceCollection::iterator it;
+
+    ALOGD("untetherInterface(%s)", interface);
+
+    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
+        if (!strcmp(interface, *it)) {
+            free(*it);
+            mInterfaces->erase(it);
+
+            return applyDnsInterfaces();
+        }
+    }
+    errno = ENOENT;
+    return -1;
+}
+
+InterfaceCollection *TetherController::getTetheredInterfaceList() {
+    return mInterfaces;
+}
diff --git a/netd/server/TetherController.h b/netd/server/TetherController.h
new file mode 100644
index 0000000..91ffb9c
--- /dev/null
+++ b/netd/server/TetherController.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _TETHER_CONTROLLER_H
+#define _TETHER_CONTROLLER_H
+
+#include <netinet/in.h>
+#include <set>
+#include <string>
+
+#include "List.h"
+
+typedef android::netd::List<char *> InterfaceCollection;
+typedef android::netd::List<struct in_addr> NetAddressCollection;
+
+class TetherController {
+    InterfaceCollection  *mInterfaces;
+    // NetId to use for forwarded DNS queries. This may not be the default
+    // network, e.g., in the case where we are tethering to a DUN APN.
+    unsigned              mDnsNetId;
+    NetAddressCollection *mDnsForwarders;
+    pid_t                 mDaemonPid;
+    int                   mDaemonFd;
+    std::set<std::string> mForwardingRequests;
+
+public:
+    TetherController();
+    virtual ~TetherController();
+
+    bool enableForwarding(const char* requester);
+    bool disableForwarding(const char* requester);
+    size_t forwardingRequestCount();
+
+    int startTethering(int num_addrs, struct in_addr* addrs);
+    int stopTethering();
+    bool isTetheringStarted();
+
+    unsigned getDnsNetId();
+    int setDnsForwarders(unsigned netId, char **servers, int numServers);
+    NetAddressCollection *getDnsForwarders();
+
+    int tetherInterface(const char *interface);
+    int untetherInterface(const char *interface);
+    InterfaceCollection *getTetheredInterfaceList();
+
+private:
+    int applyDnsInterfaces();
+    bool setIpFwdEnabled();
+};
+
+#endif
diff --git a/netd/server/UidRanges.cpp b/netd/server/UidRanges.cpp
new file mode 100644
index 0000000..10e445a
--- /dev/null
+++ b/netd/server/UidRanges.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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 "UidRanges.h"
+
+#include "NetdConstants.h"
+
+#include <stdlib.h>
+
+bool UidRanges::hasUid(uid_t uid) const {
+    auto iter = std::lower_bound(mRanges.begin(), mRanges.end(), Range(uid, uid));
+    return (iter != mRanges.end() && iter->first == uid) ||
+           (iter != mRanges.begin() && (--iter)->second >= uid);
+}
+
+const std::vector<UidRanges::Range>& UidRanges::getRanges() const {
+    return mRanges;
+}
+
+bool UidRanges::parseFrom(int argc, char* argv[]) {
+    mRanges.clear();
+    for (int i = 0; i < argc; ++i) {
+        if (!*argv[i]) {
+            // The UID string is empty.
+            return false;
+        }
+        char* endPtr;
+        uid_t uidStart = strtoul(argv[i], &endPtr, 0);
+        uid_t uidEnd;
+        if (!*endPtr) {
+            // Found a single UID. The range contains just the one UID.
+            uidEnd = uidStart;
+        } else if (*endPtr == '-') {
+            if (!*++endPtr) {
+                // Unexpected end of string.
+                return false;
+            }
+            uidEnd = strtoul(endPtr, &endPtr, 0);
+            if (*endPtr) {
+                // Illegal trailing chars.
+                return false;
+            }
+            if (uidEnd < uidStart) {
+                // Invalid order.
+                return false;
+            }
+        } else {
+            // Not a single uid, not a range. Found some other illegal char.
+            return false;
+        }
+        if (uidStart == INVALID_UID || uidEnd == INVALID_UID) {
+            // Invalid UIDs.
+            return false;
+        }
+        mRanges.push_back(Range(uidStart, uidEnd));
+    }
+    std::sort(mRanges.begin(), mRanges.end());
+    return true;
+}
+
+void UidRanges::add(const UidRanges& other) {
+    auto middle = mRanges.insert(mRanges.end(), other.mRanges.begin(), other.mRanges.end());
+    std::inplace_merge(mRanges.begin(), middle, mRanges.end());
+}
+
+void UidRanges::remove(const UidRanges& other) {
+    auto end = std::set_difference(mRanges.begin(), mRanges.end(), other.mRanges.begin(),
+                                   other.mRanges.end(), mRanges.begin());
+    mRanges.erase(end, mRanges.end());
+}
diff --git a/netd/server/UidRanges.h b/netd/server/UidRanges.h
new file mode 100644
index 0000000..044a8f9
--- /dev/null
+++ b/netd/server/UidRanges.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_SERVER_UID_RANGES_H
+#define NETD_SERVER_UID_RANGES_H
+
+#include <sys/types.h>
+#include <utility>
+#include <vector>
+
+class UidRanges {
+public:
+    typedef std::pair<uid_t, uid_t> Range;
+
+    bool hasUid(uid_t uid) const;
+    const std::vector<Range>& getRanges() const;
+
+    bool parseFrom(int argc, char* argv[]);
+
+    void add(const UidRanges& other);
+    void remove(const UidRanges& other);
+
+private:
+    std::vector<Range> mRanges;
+};
+
+#endif  // NETD_SERVER_UID_RANGES_H
diff --git a/netd/server/VirtualNetwork.cpp b/netd/server/VirtualNetwork.cpp
new file mode 100644
index 0000000..5db3645
--- /dev/null
+++ b/netd/server/VirtualNetwork.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 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 "VirtualNetwork.h"
+
+#include "RouteController.h"
+
+#define LOG_TAG "Netd"
+#include "log/log.h"
+
+VirtualNetwork::VirtualNetwork(unsigned netId, bool hasDns, bool secure) :
+        Network(netId), mHasDns(hasDns), mSecure(secure) {
+}
+
+VirtualNetwork::~VirtualNetwork() {
+}
+
+bool VirtualNetwork::getHasDns() const {
+    return mHasDns;
+}
+
+bool VirtualNetwork::isSecure() const {
+    return mSecure;
+}
+
+bool VirtualNetwork::appliesToUser(uid_t uid) const {
+    return mUidRanges.hasUid(uid);
+}
+
+int VirtualNetwork::addUsers(const UidRanges& uidRanges) {
+    for (const std::string& interface : mInterfaces) {
+        if (int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure,
+                                                                uidRanges)) {
+            ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
+            return ret;
+        }
+    }
+    mUidRanges.add(uidRanges);
+    return 0;
+}
+
+int VirtualNetwork::removeUsers(const UidRanges& uidRanges) {
+    for (const std::string& interface : mInterfaces) {
+        if (int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(),
+                                                                     mSecure, uidRanges)) {
+            ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
+            return ret;
+        }
+    }
+    mUidRanges.remove(uidRanges);
+    return 0;
+}
+
+Network::Type VirtualNetwork::getType() const {
+    return VIRTUAL;
+}
+
+int VirtualNetwork::addInterface(const std::string& interface) {
+    if (hasInterface(interface)) {
+        return 0;
+    }
+    if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure,
+                                                                mUidRanges)) {
+        ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId);
+        return ret;
+    }
+    mInterfaces.insert(interface);
+    return 0;
+}
+
+int VirtualNetwork::removeInterface(const std::string& interface) {
+    if (!hasInterface(interface)) {
+        return 0;
+    }
+    if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(),
+                                                                     mSecure, mUidRanges)) {
+        ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId);
+        return ret;
+    }
+    mInterfaces.erase(interface);
+    return 0;
+}
diff --git a/netd/server/VirtualNetwork.h b/netd/server/VirtualNetwork.h
new file mode 100644
index 0000000..d315f97
--- /dev/null
+++ b/netd/server/VirtualNetwork.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef NETD_SERVER_VIRTUAL_NETWORK_H
+#define NETD_SERVER_VIRTUAL_NETWORK_H
+
+#include "Network.h"
+#include "UidRanges.h"
+
+// A VirtualNetwork may be "secure" or not.
+//
+// A secure VPN is the usual type of VPN that grabs the default route (and thus all user traffic).
+// Only a few privileged UIDs may skip the VPN and go directly to the underlying physical network.
+//
+// A non-secure VPN ("bypassable" VPN) also grabs all user traffic by default. But all apps are
+// permitted to skip it and pick any other network for their connections.
+class VirtualNetwork : public Network {
+public:
+    VirtualNetwork(unsigned netId, bool hasDns, bool secure);
+    virtual ~VirtualNetwork();
+
+    bool getHasDns() const;
+    bool isSecure() const;
+    bool appliesToUser(uid_t uid) const;
+
+    int addUsers(const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+    int removeUsers(const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+
+private:
+    Type getType() const override;
+    int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+    int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
+
+    const bool mHasDns;
+    const bool mSecure;
+    UidRanges mUidRanges;
+};
+
+#endif  // NETD_SERVER_VIRTUAL_NETWORK_H
diff --git a/netd/server/main.cpp b/netd/server/main.cpp
new file mode 100644
index 0000000..5e189cc
--- /dev/null
+++ b/netd/server/main.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008 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 <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <fcntl.h>
+#include <dirent.h>
+
+#define LOG_TAG "Netd"
+
+#include "cutils/log.h"
+
+#include "CommandListener.h"
+#include "NetlinkManager.h"
+#include "DnsProxyListener.h"
+#include "MDnsSdListener.h"
+#include "FwmarkServer.h"
+
+static void blockSigpipe();
+static void remove_pid_file();
+static bool write_pid_file();
+
+const char* const PID_FILE_PATH = "/data/misc/net/netd_pid";
+const int PID_FILE_FLAGS = O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW | O_CLOEXEC;
+const mode_t PID_FILE_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;  // mode 0644, rw-r--r--
+
+int main() {
+
+    CommandListener *cl;
+    NetlinkManager *nm;
+    DnsProxyListener *dpl;
+    MDnsSdListener *mdnsl;
+    FwmarkServer* fwmarkServer;
+
+    ALOGI("Netd 1.0 starting");
+    remove_pid_file();
+
+    blockSigpipe();
+
+    if (!(nm = NetlinkManager::Instance())) {
+        ALOGE("Unable to create NetlinkManager");
+        exit(1);
+    };
+
+    cl = new CommandListener();
+    nm->setBroadcaster((SocketListener *) cl);
+
+    if (nm->start()) {
+        ALOGE("Unable to start NetlinkManager (%s)", strerror(errno));
+        exit(1);
+    }
+
+    // Set local DNS mode, to prevent bionic from proxying
+    // back to this service, recursively.
+    setenv("ANDROID_DNS_MODE", "local", 1);
+    dpl = new DnsProxyListener(CommandListener::sNetCtrl);
+    if (dpl->startListener()) {
+        ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno));
+        exit(1);
+    }
+
+    mdnsl = new MDnsSdListener();
+    if (mdnsl->startListener()) {
+        ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno));
+        exit(1);
+    }
+
+    fwmarkServer = new FwmarkServer(CommandListener::sNetCtrl);
+    if (fwmarkServer->startListener()) {
+        ALOGE("Unable to start FwmarkServer (%s)", strerror(errno));
+        exit(1);
+    }
+
+    /*
+     * Now that we're up, we can respond to commands
+     */
+    if (cl->startListener()) {
+        ALOGE("Unable to start CommandListener (%s)", strerror(errno));
+        exit(1);
+    }
+
+    bool wrote_pid = write_pid_file();
+
+    while(1) {
+        sleep(30); // 30 sec
+        if (!wrote_pid) {
+            wrote_pid = write_pid_file();
+        }
+    }
+
+    ALOGI("Netd exiting");
+    remove_pid_file();
+    exit(0);
+}
+
+static bool write_pid_file() {
+    char pid_buf[20];  // current pid_max is 32768, so plenty of room
+    snprintf(pid_buf, sizeof(pid_buf), "%ld\n", (long)getpid());
+
+    int fd = open(PID_FILE_PATH, PID_FILE_FLAGS, PID_FILE_MODE);
+    if (fd == -1) {
+        ALOGE("Unable to create pid file (%s)", strerror(errno));
+        return false;
+    }
+
+    // File creation is affected by umask, so make sure the right mode bits are set.
+    if (fchmod(fd, PID_FILE_MODE) == -1) {
+        ALOGE("failed to set mode 0%o on %s (%s)", PID_FILE_MODE, PID_FILE_PATH, strerror(errno));
+        close(fd);
+        remove_pid_file();
+        return false;
+    }
+
+    if (write(fd, pid_buf, strlen(pid_buf)) != (ssize_t)strlen(pid_buf)) {
+        ALOGE("Unable to write to pid file (%s)", strerror(errno));
+        close(fd);
+        remove_pid_file();
+        return false;
+    }
+    close(fd);
+    return true;
+}
+
+static void remove_pid_file() {
+    unlink(PID_FILE_PATH);
+}
+
+static void blockSigpipe()
+{
+    sigset_t mask;
+
+    sigemptyset(&mask);
+    sigaddset(&mask, SIGPIPE);
+    if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
+        ALOGW("WARNING: SIGPIPE not blocked\n");
+}
diff --git a/netd/server/ndc.cpp b/netd/server/ndc.cpp
new file mode 100644
index 0000000..14f6654
--- /dev/null
+++ b/netd/server/ndc.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2008 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+#include <cutils/sockets.h>
+#include <private/android_filesystem_config.h>
+
+static void usage(char *progname);
+static int do_monitor(int sock, int stop_after_cmd);
+static int do_cmd(int sock, int argc, char **argv);
+
+int main(int argc, char **argv) {
+    int sock;
+    int cmdOffset = 0;
+
+    if (argc < 2)
+        usage(argv[0]);
+
+    // try interpreting the first arg as the socket name - if it fails go back to netd
+
+    if ((sock = socket_local_client(argv[1],
+                                     ANDROID_SOCKET_NAMESPACE_RESERVED,
+                                     SOCK_STREAM)) < 0) {
+        if ((sock = socket_local_client("netd",
+                                         ANDROID_SOCKET_NAMESPACE_RESERVED,
+                                         SOCK_STREAM)) < 0) {
+            fprintf(stderr, "Error connecting (%s)\n", strerror(errno));
+            exit(4);
+        }
+    } else {
+        if (argc < 3) usage(argv[0]);
+        printf("Using alt socket %s\n", argv[1]);
+        cmdOffset = 1;
+    }
+
+    if (!strcmp(argv[1+cmdOffset], "monitor"))
+        exit(do_monitor(sock, 0));
+    exit(do_cmd(sock, argc-cmdOffset, &(argv[cmdOffset])));
+}
+
+static int do_cmd(int sock, int argc, char **argv) {
+    char *final_cmd;
+    char *conv_ptr;
+    int i;
+
+    /* Check if 1st arg is cmd sequence number */ 
+    strtol(argv[1], &conv_ptr, 10);
+    if (conv_ptr == argv[1]) {
+        final_cmd = strdup("0 ");
+    } else {
+        final_cmd = strdup("");
+    }
+    if (final_cmd == NULL) {
+        int res = errno;
+        perror("strdup failed");
+        return res;
+    }
+
+    for (i = 1; i < argc; i++) {
+        if (strchr(argv[i], '"')) {
+            perror("argument with embedded quotes not allowed");
+            free(final_cmd);
+            return 1;
+        }
+        bool needs_quoting = strchr(argv[i], ' ');
+        const char *format = needs_quoting ? "%s\"%s\"%s" : "%s%s%s";
+        char *tmp_final_cmd;
+
+        if (asprintf(&tmp_final_cmd, format, final_cmd, argv[i],
+                     (i == (argc - 1)) ? "" : " ") < 0) {
+            int res = errno;
+            perror("failed asprintf");
+            free(final_cmd);
+            return res;
+        }
+        free(final_cmd);
+        final_cmd = tmp_final_cmd;
+    }
+
+    if (write(sock, final_cmd, strlen(final_cmd) + 1) < 0) {
+        int res = errno;
+        perror("write");
+        free(final_cmd);
+        return res;
+    }
+    free(final_cmd);
+
+    return do_monitor(sock, 1);
+}
+
+static int do_monitor(int sock, int stop_after_cmd) {
+    char *buffer = (char *)malloc(4096);
+
+    if (!stop_after_cmd)
+        printf("[Connected to Netd]\n");
+
+    while(1) {
+        fd_set read_fds;
+        struct timeval to;
+        int rc = 0;
+
+        to.tv_sec = 10;
+        to.tv_usec = 0;
+
+        FD_ZERO(&read_fds);
+        FD_SET(sock, &read_fds);
+
+        rc = TEMP_FAILURE_RETRY(select(sock +1, &read_fds, NULL, NULL, &to));
+        if (rc < 0) {
+            int res = errno;
+            fprintf(stderr, "Error in select (%s)\n", strerror(res));
+            free(buffer);
+            return res;
+        }
+        if (rc == 0) {
+            continue;
+        }
+        if (!FD_ISSET(sock, &read_fds)) {
+            continue;
+        }
+
+        memset(buffer, 0, 4096);
+        if ((rc = read(sock, buffer, 4096)) <= 0) {
+            int res = errno;
+            if (rc == 0)
+                fprintf(stderr, "Lost connection to Netd - did it crash?\n");
+            else
+                fprintf(stderr, "Error reading data (%s)\n", strerror(res));
+            free(buffer);
+            if (rc == 0)
+                return ECONNRESET;
+            return res;
+        }
+
+        int offset = 0;
+        int i = 0;
+
+        for (i = 0; i < rc; i++) {
+            if (buffer[i] == '\0') {
+                int code;
+                char tmp[4];
+
+                strncpy(tmp, buffer + offset, 3);
+                tmp[3] = '\0';
+                code = atoi(tmp);
+
+                printf("%s\n", buffer + offset);
+                if (stop_after_cmd) {
+                    if (code >= 200 && code < 600)
+                        return 0;
+                }
+                offset = i + 1;
+            }
+        }
+    }
+    free(buffer);
+    return 0;
+}
+
+static void usage(char *progname) {
+    fprintf(stderr, "Usage: %s [<sockname>] ([monitor] | ([<cmd_seq_num>] <cmd> [arg ...]))\n", progname);
+    exit(1);
+}
diff --git a/netd/server/netd.rc b/netd/server/netd.rc
new file mode 100644
index 0000000..4fc6fd8
--- /dev/null
+++ b/netd/server/netd.rc
@@ -0,0 +1,6 @@
+service netd /system/bin/netd
+    class main
+    socket netd stream 0660 root system
+    socket dnsproxyd stream 0660 root inet
+    socket mdns stream 0660 root system
+    socket fwmarkd stream 0660 root inet
diff --git a/netd/server/oem_iptables_hook.cpp b/netd/server/oem_iptables_hook.cpp
new file mode 100644
index 0000000..7e4b3cb
--- /dev/null
+++ b/netd/server/oem_iptables_hook.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LOG_TAG "OemIptablesHook"
+#include <cutils/log.h>
+#include <logwrap/logwrap.h>
+#include "NetdConstants.h"
+
+static int runIptablesCmd(int argc, const char **argv) {
+    int res;
+
+    res = android_fork_execvp(argc, (char **)argv, NULL, false, false);
+    return res;
+}
+
+static bool oemCleanupHooks() {
+    const char *cmd1[] = {
+            IPTABLES_PATH,
+            "-w",
+            "-F",
+            "oem_out"
+    };
+    runIptablesCmd(ARRAY_SIZE(cmd1), cmd1);
+
+    const char *cmd2[] = {
+            IPTABLES_PATH,
+            "-w",
+            "-F",
+            "oem_fwd"
+    };
+    runIptablesCmd(ARRAY_SIZE(cmd2), cmd2);
+
+    const char *cmd3[] = {
+            IPTABLES_PATH,
+            "-w",
+            "-t",
+            "nat",
+            "-F",
+            "oem_nat_pre"
+    };
+    runIptablesCmd(ARRAY_SIZE(cmd3), cmd3);
+    return true;
+}
+
+static bool oemInitChains() {
+    int ret = system(OEM_SCRIPT_PATH);
+    if ((-1 == ret) || (0 != WEXITSTATUS(ret))) {
+        ALOGE("%s failed: %s", OEM_SCRIPT_PATH, strerror(errno));
+        oemCleanupHooks();
+        return false;
+    }
+    return true;
+}
+
+
+void setupOemIptablesHook() {
+    if (0 == access(OEM_SCRIPT_PATH, R_OK | X_OK)) {
+        // The call to oemCleanupHooks() is superfluous when done on bootup,
+        // but is needed for the case where netd has crashed/stopped and is
+        // restarted.
+        if (oemCleanupHooks() && oemInitChains()) {
+            ALOGI("OEM iptable hook installed.");
+        }
+    }
+}
diff --git a/netd/server/oem_iptables_hook.h b/netd/server/oem_iptables_hook.h
new file mode 100644
index 0000000..bc99638
--- /dev/null
+++ b/netd/server/oem_iptables_hook.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef _OEM_IPTABLES_HOOK_H
+#define _OEM_IPTABLES_HOOK_H
+
+#define OEM_IPTABLES_FILTER_OUTPUT "oem_out"
+#define OEM_IPTABLES_FILTER_FORWARD "oem_fwd"
+#define OEM_IPTABLES_NAT_PREROUTING "oem_nat_pre"
+
+void setupOemIptablesHook();
+
+#endif
diff --git a/netd/tests/Android.mk b/netd/tests/Android.mk
new file mode 100644
index 0000000..211411b
--- /dev/null
+++ b/netd/tests/Android.mk
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := sock_diag_test
+LOCAL_CFLAGS := -Wall -Werror -Wunused-parameter
+LOCAL_C_INCLUDES := system/netd/server
+LOCAL_SRC_FILES := sock_diag_test.cpp ../server/SockDiag.cpp
+LOCAL_MODULE_TAGS := tests
+LOCAL_SHARED_LIBRARIES := liblog
+include $(BUILD_NATIVE_TEST)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := netd_test
+EXTRA_LDLIBS := -lpthread
+LOCAL_SHARED_LIBRARIES += libbase libcutils libutils liblog libnetd_client
+LOCAL_STATIC_LIBRARIES += libtestUtil
+LOCAL_C_INCLUDES += system/core/base/include system/netd/include \
+                    system/extras/tests/include bionic/libc/dns/include
+LOCAL_SRC_FILES := netd_test.cpp dns_responder.cpp
+LOCAL_MODULE_TAGS := eng tests
+include $(BUILD_NATIVE_TEST)
diff --git a/netd/tests/dns_responder.cpp b/netd/tests/dns_responder.cpp
new file mode 100644
index 0000000..09d6379
--- /dev/null
+++ b/netd/tests/dns_responder.cpp
@@ -0,0 +1,841 @@
+/*
+ * 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.
+ */
+
+#include "dns_responder.h"
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <vector>
+
+#include <log/log.h>
+
+namespace test {
+
+std::string errno2str() {
+    char error_msg[512] = { 0 };
+    if (strerror_r(errno, error_msg, sizeof(error_msg)))
+        return std::string();
+    return std::string(error_msg);
+}
+
+#define APLOGI(fmt, ...) ALOGI(fmt ": [%d] %s", __VA_ARGS__, errno, errno2str().c_str())
+
+std::string str2hex(const char* buffer, size_t len) {
+    std::string str(len*2, '\0');
+    for (size_t i = 0 ; i < len ; ++i) {
+        static const char* hex = "0123456789ABCDEF";
+        uint8_t c = buffer[i];
+        str[i*2] = hex[c >> 4];
+        str[i*2 + 1] = hex[c & 0x0F];
+    }
+    return str;
+}
+
+std::string addr2str(const sockaddr* sa, socklen_t sa_len) {
+    char host_str[NI_MAXHOST] = { 0 };
+    int rv = getnameinfo(sa, sa_len, host_str, sizeof(host_str), nullptr, 0,
+                         NI_NUMERICHOST);
+    if (rv == 0) return std::string(host_str);
+    return std::string();
+}
+
+/* DNS struct helpers */
+
+const char* dnstype2str(unsigned dnstype) {
+    static std::unordered_map<unsigned, const char*> kTypeStrs = {
+        { ns_type::ns_t_a, "A" },
+        { ns_type::ns_t_ns, "NS" },
+        { ns_type::ns_t_md, "MD" },
+        { ns_type::ns_t_mf, "MF" },
+        { ns_type::ns_t_cname, "CNAME" },
+        { ns_type::ns_t_soa, "SOA" },
+        { ns_type::ns_t_mb, "MB" },
+        { ns_type::ns_t_mb, "MG" },
+        { ns_type::ns_t_mr, "MR" },
+        { ns_type::ns_t_null, "NULL" },
+        { ns_type::ns_t_wks, "WKS" },
+        { ns_type::ns_t_ptr, "PTR" },
+        { ns_type::ns_t_hinfo, "HINFO" },
+        { ns_type::ns_t_minfo, "MINFO" },
+        { ns_type::ns_t_mx, "MX" },
+        { ns_type::ns_t_txt, "TXT" },
+        { ns_type::ns_t_rp, "RP" },
+        { ns_type::ns_t_afsdb, "AFSDB" },
+        { ns_type::ns_t_x25, "X25" },
+        { ns_type::ns_t_isdn, "ISDN" },
+        { ns_type::ns_t_rt, "RT" },
+        { ns_type::ns_t_nsap, "NSAP" },
+        { ns_type::ns_t_nsap_ptr, "NSAP-PTR" },
+        { ns_type::ns_t_sig, "SIG" },
+        { ns_type::ns_t_key, "KEY" },
+        { ns_type::ns_t_px, "PX" },
+        { ns_type::ns_t_gpos, "GPOS" },
+        { ns_type::ns_t_aaaa, "AAAA" },
+        { ns_type::ns_t_loc, "LOC" },
+        { ns_type::ns_t_nxt, "NXT" },
+        { ns_type::ns_t_eid, "EID" },
+        { ns_type::ns_t_nimloc, "NIMLOC" },
+        { ns_type::ns_t_srv, "SRV" },
+        { ns_type::ns_t_naptr, "NAPTR" },
+        { ns_type::ns_t_kx, "KX" },
+        { ns_type::ns_t_cert, "CERT" },
+        { ns_type::ns_t_a6, "A6" },
+        { ns_type::ns_t_dname, "DNAME" },
+        { ns_type::ns_t_sink, "SINK" },
+        { ns_type::ns_t_opt, "OPT" },
+        { ns_type::ns_t_apl, "APL" },
+        { ns_type::ns_t_tkey, "TKEY" },
+        { ns_type::ns_t_tsig, "TSIG" },
+        { ns_type::ns_t_ixfr, "IXFR" },
+        { ns_type::ns_t_axfr, "AXFR" },
+        { ns_type::ns_t_mailb, "MAILB" },
+        { ns_type::ns_t_maila, "MAILA" },
+        { ns_type::ns_t_any, "ANY" },
+        { ns_type::ns_t_zxfr, "ZXFR" },
+    };
+    auto it = kTypeStrs.find(dnstype);
+    static const char* kUnknownStr{ "UNKNOWN" };
+    if (it == kTypeStrs.end()) return kUnknownStr;
+    return it->second;
+}
+
+const char* dnsclass2str(unsigned dnsclass) {
+    static std::unordered_map<unsigned, const char*> kClassStrs = {
+        { ns_class::ns_c_in , "Internet" },
+        { 2, "CSNet" },
+        { ns_class::ns_c_chaos, "ChaosNet" },
+        { ns_class::ns_c_hs, "Hesiod" },
+        { ns_class::ns_c_none, "none" },
+        { ns_class::ns_c_any, "any" }
+    };
+    auto it = kClassStrs.find(dnsclass);
+    static const char* kUnknownStr{ "UNKNOWN" };
+    if (it == kClassStrs.end()) return kUnknownStr;
+    return it->second;
+    return "unknown";
+}
+
+struct DNSName {
+    std::string name;
+    const char* read(const char* buffer, const char* buffer_end);
+    char* write(char* buffer, const char* buffer_end) const;
+    const char* toString() const;
+private:
+    const char* parseField(const char* buffer, const char* buffer_end,
+                           bool* last);
+};
+
+const char* DNSName::toString() const {
+    return name.c_str();
+}
+
+const char* DNSName::read(const char* buffer, const char* buffer_end) {
+    const char* cur = buffer;
+    bool last = false;
+    do {
+        cur = parseField(cur, buffer_end, &last);
+        if (cur == nullptr) {
+            ALOGI("parsing failed at line %d", __LINE__);
+            return nullptr;
+        }
+    } while (!last);
+    return cur;
+}
+
+char* DNSName::write(char* buffer, const char* buffer_end) const {
+    char* buffer_cur = buffer;
+    for (size_t pos = 0 ; pos < name.size() ; ) {
+        size_t dot_pos = name.find('.', pos);
+        if (dot_pos == std::string::npos) {
+            // Sanity check, should never happen unless parseField is broken.
+            ALOGI("logic error: all names are expected to end with a '.'");
+            return nullptr;
+        }
+        size_t len = dot_pos - pos;
+        if (len >= 256) {
+            ALOGI("name component '%s' is %zu long, but max is 255",
+                    name.substr(pos, dot_pos - pos).c_str(), len);
+            return nullptr;
+        }
+        if (buffer_cur + sizeof(uint8_t) + len > buffer_end) {
+            ALOGI("buffer overflow at line %d", __LINE__);
+            return nullptr;
+        }
+        *buffer_cur++ = len;
+        buffer_cur = std::copy(std::next(name.begin(), pos),
+                               std::next(name.begin(), dot_pos),
+                               buffer_cur);
+        pos = dot_pos + 1;
+    }
+    // Write final zero.
+    *buffer_cur++ = 0;
+    return buffer_cur;
+}
+
+const char* DNSName::parseField(const char* buffer, const char* buffer_end,
+                                bool* last) {
+    if (buffer + sizeof(uint8_t) > buffer_end) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    unsigned field_type = *buffer >> 6;
+    unsigned ofs = *buffer & 0x3F;
+    const char* cur = buffer + sizeof(uint8_t);
+    if (field_type == 0) {
+        // length + name component
+        if (ofs == 0) {
+            *last = true;
+            return cur;
+        }
+        if (cur + ofs > buffer_end) {
+            ALOGI("parsing failed at line %d", __LINE__);
+            return nullptr;
+        }
+        name.append(cur, ofs);
+        name.push_back('.');
+        return cur + ofs;
+    } else if (field_type == 3) {
+        ALOGI("name compression not implemented");
+        return nullptr;
+    }
+    ALOGI("invalid name field type");
+    return nullptr;
+}
+
+struct DNSQuestion {
+    DNSName qname;
+    unsigned qtype;
+    unsigned qclass;
+    const char* read(const char* buffer, const char* buffer_end);
+    char* write(char* buffer, const char* buffer_end) const;
+    std::string toString() const;
+};
+
+const char* DNSQuestion::read(const char* buffer, const char* buffer_end) {
+    const char* cur = qname.read(buffer, buffer_end);
+    if (cur == nullptr) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    if (cur + 2*sizeof(uint16_t) > buffer_end) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    qtype = ntohs(*reinterpret_cast<const uint16_t*>(cur));
+    qclass = ntohs(*reinterpret_cast<const uint16_t*>(cur + sizeof(uint16_t)));
+    return cur + 2*sizeof(uint16_t);
+}
+
+char* DNSQuestion::write(char* buffer, const char* buffer_end) const {
+    char* buffer_cur = qname.write(buffer, buffer_end);
+    if (buffer_cur == nullptr) return nullptr;
+    if (buffer_cur + 2*sizeof(uint16_t) > buffer_end) {
+        ALOGI("buffer overflow on line %d", __LINE__);
+        return nullptr;
+    }
+    *reinterpret_cast<uint16_t*>(buffer_cur) = htons(qtype);
+    *reinterpret_cast<uint16_t*>(buffer_cur + sizeof(uint16_t)) =
+            htons(qclass);
+    return buffer_cur + 2*sizeof(uint16_t);
+}
+
+std::string DNSQuestion::toString() const {
+    char buffer[4096];
+    int len = snprintf(buffer, sizeof(buffer), "Q<%s,%s,%s>", qname.toString(),
+                       dnstype2str(qtype), dnsclass2str(qclass));
+    return std::string(buffer, len);
+}
+
+struct DNSRecord {
+    DNSName name;
+    unsigned rtype;
+    unsigned rclass;
+    unsigned ttl;
+    std::vector<char> rdata;
+    const char* read(const char* buffer, const char* buffer_end);
+    char* write(char* buffer, const char* buffer_end) const;
+    std::string toString() const;
+private:
+    struct IntFields {
+        uint16_t rtype;
+        uint16_t rclass;
+        uint32_t ttl;
+        uint16_t rdlen;
+    } __attribute__((__packed__));
+
+    const char* readIntFields(const char* buffer, const char* buffer_end,
+            unsigned* rdlen);
+    char* writeIntFields(unsigned rdlen, char* buffer,
+                         const char* buffer_end) const;
+};
+
+const char* DNSRecord::read(const char* buffer, const char* buffer_end) {
+    const char* cur = name.read(buffer, buffer_end);
+    if (cur == nullptr) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    unsigned rdlen = 0;
+    cur = readIntFields(cur, buffer_end, &rdlen);
+    if (cur == nullptr) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    if (cur + rdlen > buffer_end) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    rdata.assign(cur, cur + rdlen);
+    return cur + rdlen;
+}
+
+char* DNSRecord::write(char* buffer, const char* buffer_end) const {
+    char* buffer_cur = name.write(buffer, buffer_end);
+    if (buffer_cur == nullptr) return nullptr;
+    buffer_cur = writeIntFields(rdata.size(), buffer_cur, buffer_end);
+    if (buffer_cur == nullptr) return nullptr;
+    if (buffer_cur + rdata.size() > buffer_end) {
+        ALOGI("buffer overflow on line %d", __LINE__);
+        return nullptr;
+    }
+    return std::copy(rdata.begin(), rdata.end(), buffer_cur);
+}
+
+std::string DNSRecord::toString() const {
+    char buffer[4096];
+    int len = snprintf(buffer, sizeof(buffer), "R<%s,%s,%s>", name.toString(),
+                       dnstype2str(rtype), dnsclass2str(rclass));
+    return std::string(buffer, len);
+}
+
+const char* DNSRecord::readIntFields(const char* buffer, const char* buffer_end,
+                                     unsigned* rdlen) {
+    if (buffer + sizeof(IntFields) > buffer_end ) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    const auto& intfields = *reinterpret_cast<const IntFields*>(buffer);
+    rtype = ntohs(intfields.rtype);
+    rclass = ntohs(intfields.rclass);
+    ttl = ntohl(intfields.ttl);
+    *rdlen = ntohs(intfields.rdlen);
+    return buffer + sizeof(IntFields);
+}
+
+char* DNSRecord::writeIntFields(unsigned rdlen, char* buffer,
+                                const char* buffer_end) const {
+    if (buffer + sizeof(IntFields) > buffer_end ) {
+        ALOGI("buffer overflow on line %d", __LINE__);
+        return nullptr;
+    }
+    auto& intfields = *reinterpret_cast<IntFields*>(buffer);
+    intfields.rtype = htons(rtype);
+    intfields.rclass = htons(rclass);
+    intfields.ttl = htonl(ttl);
+    intfields.rdlen = htons(rdlen);
+    return buffer + sizeof(IntFields);
+}
+
+struct DNSHeader {
+    unsigned id;
+    bool ra;
+    uint8_t rcode;
+    bool qr;
+    uint8_t opcode;
+    bool aa;
+    bool tr;
+    bool rd;
+    std::vector<DNSQuestion> questions;
+    std::vector<DNSRecord> answers;
+    std::vector<DNSRecord> authorities;
+    std::vector<DNSRecord> additionals;
+    const char* read(const char* buffer, const char* buffer_end);
+    char* write(char* buffer, const char* buffer_end) const;
+    std::string toString() const;
+
+private:
+    struct Header {
+        uint16_t id;
+        uint8_t flags0;
+        uint8_t flags1;
+        uint16_t qdcount;
+        uint16_t ancount;
+        uint16_t nscount;
+        uint16_t arcount;
+    } __attribute__((__packed__));
+
+    const char* readHeader(const char* buffer, const char* buffer_end,
+                           unsigned* qdcount, unsigned* ancount,
+                           unsigned* nscount, unsigned* arcount);
+};
+
+const char* DNSHeader::read(const char* buffer, const char* buffer_end) {
+    unsigned qdcount;
+    unsigned ancount;
+    unsigned nscount;
+    unsigned arcount;
+    const char* cur = readHeader(buffer, buffer_end, &qdcount, &ancount,
+                                 &nscount, &arcount);
+    if (cur == nullptr) {
+        ALOGI("parsing failed at line %d", __LINE__);
+        return nullptr;
+    }
+    if (qdcount) {
+        questions.resize(qdcount);
+        for (unsigned i = 0 ; i < qdcount ; ++i) {
+            cur = questions[i].read(cur, buffer_end);
+            if (cur == nullptr) {
+                ALOGI("parsing failed at line %d", __LINE__);
+                return nullptr;
+            }
+        }
+    }
+    if (ancount) {
+        answers.resize(ancount);
+        for (unsigned i = 0 ; i < ancount ; ++i) {
+            cur = answers[i].read(cur, buffer_end);
+            if (cur == nullptr) {
+                ALOGI("parsing failed at line %d", __LINE__);
+                return nullptr;
+            }
+        }
+    }
+    if (nscount) {
+        authorities.resize(nscount);
+        for (unsigned i = 0 ; i < nscount ; ++i) {
+            cur = authorities[i].read(cur, buffer_end);
+            if (cur == nullptr) {
+                ALOGI("parsing failed at line %d", __LINE__);
+                return nullptr;
+            }
+        }
+    }
+    if (arcount) {
+        additionals.resize(arcount);
+        for (unsigned i = 0 ; i < arcount ; ++i) {
+            cur = additionals[i].read(cur, buffer_end);
+            if (cur == nullptr) {
+                ALOGI("parsing failed at line %d", __LINE__);
+                return nullptr;
+            }
+        }
+    }
+    return cur;
+}
+
+char* DNSHeader::write(char* buffer, const char* buffer_end) const {
+    if (buffer + sizeof(Header) > buffer_end) {
+        ALOGI("buffer overflow on line %d", __LINE__);
+        return nullptr;
+    }
+    Header& header = *reinterpret_cast<Header*>(buffer);
+    // bytes 0-1
+    header.id = htons(id);
+    // byte 2: 7:qr, 3-6:opcode, 2:aa, 1:tr, 0:rd
+    header.flags0 = (qr << 7) | (opcode << 3) | (aa << 2) | (tr << 1) | rd;
+    // byte 3: 7:ra, 6:zero, 5:ad, 4:cd, 0-3:rcode
+    header.flags1 = rcode;
+    // rest of header
+    header.qdcount = htons(questions.size());
+    header.ancount = htons(answers.size());
+    header.nscount = htons(authorities.size());
+    header.arcount = htons(additionals.size());
+    char* buffer_cur = buffer + sizeof(Header);
+    for (const DNSQuestion& question : questions) {
+        buffer_cur = question.write(buffer_cur, buffer_end);
+        if (buffer_cur == nullptr) return nullptr;
+    }
+    for (const DNSRecord& answer : answers) {
+        buffer_cur = answer.write(buffer_cur, buffer_end);
+        if (buffer_cur == nullptr) return nullptr;
+    }
+    for (const DNSRecord& authority : authorities) {
+        buffer_cur = authority.write(buffer_cur, buffer_end);
+        if (buffer_cur == nullptr) return nullptr;
+    }
+    for (const DNSRecord& additional : additionals) {
+        buffer_cur = additional.write(buffer_cur, buffer_end);
+        if (buffer_cur == nullptr) return nullptr;
+    }
+    return buffer_cur;
+}
+
+std::string DNSHeader::toString() const {
+    // TODO
+    return std::string();
+}
+
+const char* DNSHeader::readHeader(const char* buffer, const char* buffer_end,
+                                  unsigned* qdcount, unsigned* ancount,
+                                  unsigned* nscount, unsigned* arcount) {
+    if (buffer + sizeof(Header) > buffer_end)
+        return 0;
+    const auto& header = *reinterpret_cast<const Header*>(buffer);
+    // bytes 0-1
+    id = ntohs(header.id);
+    // byte 2: 7:qr, 3-6:opcode, 2:aa, 1:tr, 0:rd
+    qr = header.flags0 >> 7;
+    opcode = (header.flags0 >> 3) & 0x0F;
+    aa = (header.flags0 >> 2) & 1;
+    tr = (header.flags0 >> 1) & 1;
+    rd = header.flags0 & 1;
+    // byte 3: 7:ra, 6:zero, 5:ad, 4:cd, 0-3:rcode
+    ra = header.flags1 >> 7;
+    rcode = header.flags1 & 0xF;
+    // rest of header
+    *qdcount = ntohs(header.qdcount);
+    *ancount = ntohs(header.ancount);
+    *nscount = ntohs(header.nscount);
+    *arcount = ntohs(header.arcount);
+    return buffer + sizeof(Header);
+}
+
+/* DNS responder */
+
+DNSResponder::DNSResponder(const char* listen_address,
+                           const char* listen_service, int poll_timeout_ms,
+                           uint16_t error_rcode, double response_probability) :
+    listen_address_(listen_address), listen_service_(listen_service),
+    poll_timeout_ms_(poll_timeout_ms), error_rcode_(error_rcode),
+    response_probability_(response_probability),
+    socket_(-1), epoll_fd_(-1), terminate_(false) { }
+
+DNSResponder::~DNSResponder() {
+    stopServer();
+}
+
+void DNSResponder::addMapping(const char* name, ns_type type,
+        const char* addr) {
+    std::lock_guard<std::mutex> lock(mappings_mutex_);
+    auto it = mappings_.find(QueryKey(name, type));
+    if (it != mappings_.end()) {
+        ALOGI("Overwriting mapping for (%s, %s), previous address %s, new "
+            "address %s", name, dnstype2str(type), it->second.c_str(),
+            addr);
+        it->second = addr;
+        return;
+    }
+    mappings_.emplace(std::piecewise_construct,
+                      std::forward_as_tuple(name, type),
+                      std::forward_as_tuple(addr));
+}
+
+void DNSResponder::removeMapping(const char* name, ns_type type) {
+    std::lock_guard<std::mutex> lock(mappings_mutex_);
+    auto it = mappings_.find(QueryKey(name, type));
+    if (it != mappings_.end()) {
+        ALOGI("Cannot remove mapping mapping from (%s, %s), not present", name,
+            dnstype2str(type));
+        return;
+    }
+    mappings_.erase(it);
+}
+
+void DNSResponder::setResponseProbability(double response_probability) {
+    response_probability_ = response_probability;
+}
+
+bool DNSResponder::running() const {
+    return socket_ != -1;
+}
+
+bool DNSResponder::startServer() {
+    if (running()) {
+        ALOGI("server already running");
+        return false;
+    }
+    addrinfo ai_hints{
+        .ai_family = AF_UNSPEC,
+        .ai_socktype = SOCK_DGRAM,
+        .ai_flags = AI_PASSIVE
+    };
+    addrinfo* ai_res;
+    int rv = getaddrinfo(listen_address_.c_str(), listen_service_.c_str(),
+                         &ai_hints, &ai_res);
+    if (rv) {
+        ALOGI("getaddrinfo(%s, %s) failed: %s", listen_address_.c_str(),
+            listen_service_.c_str(), gai_strerror(rv));
+        return false;
+    }
+    int s = -1;
+    for (const addrinfo* ai = ai_res ; ai ; ai = ai->ai_next) {
+        s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+        if (s < 0) continue;
+        const int one = 1;
+        setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
+        if (bind(s, ai->ai_addr, ai->ai_addrlen)) {
+            APLOGI("bind failed for socket %d", s);
+            close(s);
+            s = -1;
+            continue;
+        }
+        std::string host_str = addr2str(ai->ai_addr, ai->ai_addrlen);
+        ALOGI("bound to UDP %s:%s", host_str.c_str(), listen_service_.c_str());
+        break;
+    }
+    freeaddrinfo(ai_res);
+    if (s < 0) {
+        ALOGI("bind() failed");
+        return false;
+    }
+
+    int flags = fcntl(s, F_GETFL, 0);
+    if (flags < 0) flags = 0;
+    if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
+        APLOGI("fcntl(F_SETFL) failed for socket %d", s);
+        close(s);
+        return false;
+    }
+
+    int ep_fd = epoll_create(1);
+    if (ep_fd < 0) {
+        char error_msg[512] = { 0 };
+        if (strerror_r(errno, error_msg, sizeof(error_msg)))
+            strncpy(error_msg, "UNKNOWN", sizeof(error_msg));
+        APLOGI("epoll_create() failed: %s", error_msg);
+        close(s);
+        return false;
+    }
+    epoll_event ev;
+    ev.events = EPOLLIN;
+    ev.data.fd = s;
+    if (epoll_ctl(ep_fd, EPOLL_CTL_ADD, s, &ev) < 0) {
+        APLOGI("epoll_ctl() failed for socket %d", s);
+        close(ep_fd);
+        close(s);
+        return false;
+    }
+
+    epoll_fd_ = ep_fd;
+    socket_ = s;
+    {
+        std::lock_guard<std::mutex> lock(update_mutex_);
+        handler_thread_ = std::thread(&DNSResponder::requestHandler, this);
+    }
+    ALOGI("server started successfully");
+    return true;
+}
+
+bool DNSResponder::stopServer() {
+    std::lock_guard<std::mutex> lock(update_mutex_);
+    if (!running()) {
+        ALOGI("server not running");
+        return false;
+    }
+    if (terminate_) {
+        ALOGI("LOGIC ERROR");
+        return false;
+    }
+    ALOGI("stopping server");
+    terminate_ = true;
+    handler_thread_.join();
+    close(epoll_fd_);
+    close(socket_);
+    terminate_ = false;
+    socket_ = -1;
+    ALOGI("server stopped successfully");
+    return true;
+}
+
+std::vector<std::pair<std::string, ns_type >> DNSResponder::queries() const {
+    std::lock_guard<std::mutex> lock(queries_mutex_);
+    return queries_;
+}
+
+void DNSResponder::clearQueries() {
+    std::lock_guard<std::mutex> lock(queries_mutex_);
+    queries_.clear();
+}
+
+void DNSResponder::requestHandler() {
+    epoll_event evs[1];
+    while (!terminate_) {
+        int n = epoll_wait(epoll_fd_, evs, 1, poll_timeout_ms_);
+        if (n == 0) continue;
+        if (n < 0) {
+            ALOGI("epoll_wait() failed");
+            // TODO(imaipi): terminate on error.
+            return;
+        }
+        char buffer[4096];
+        sockaddr_storage sa;
+        socklen_t sa_len = sizeof(sa);
+        ssize_t len;
+        do {
+            len = recvfrom(socket_, buffer, sizeof(buffer), 0,
+                           (sockaddr*) &sa, &sa_len);
+        } while (len < 0 && (errno == EAGAIN || errno == EINTR));
+        if (len <= 0) {
+            ALOGI("recvfrom() failed");
+            continue;
+        }
+        ALOGI("read %zd bytes", len);
+        char response[4096];
+        size_t response_len = sizeof(response);
+        if (handleDNSRequest(buffer, len, response, &response_len) &&
+            response_len > 0) {
+            len = sendto(socket_, response, response_len, 0,
+                         reinterpret_cast<const sockaddr*>(&sa), sa_len);
+            std::string host_str =
+                addr2str(reinterpret_cast<const sockaddr*>(&sa), sa_len);
+            if (len > 0) {
+                ALOGI("sent %zu bytes to %s", len, host_str.c_str());
+            } else {
+                APLOGI("sendto() failed for %s", host_str.c_str());
+            }
+            // Test that the response is actually a correct DNS message.
+            const char* response_end = response + len;
+            DNSHeader header;
+            const char* cur = header.read(response, response_end);
+            if (cur == nullptr) ALOGI("response is flawed");
+
+        } else {
+            ALOGI("not responding");
+        }
+    }
+}
+
+bool DNSResponder::handleDNSRequest(const char* buffer, ssize_t len,
+                                    char* response, size_t* response_len)
+                                    const {
+    ALOGI("request: '%s'", str2hex(buffer, len).c_str());
+    const char* buffer_end = buffer + len;
+    DNSHeader header;
+    const char* cur = header.read(buffer, buffer_end);
+    // TODO(imaipi): for now, unparsable messages are silently dropped, fix.
+    if (cur == nullptr) {
+        ALOGI("failed to parse query");
+        return false;
+    }
+    if (header.qr) {
+        ALOGI("response received instead of a query");
+        return false;
+    }
+    if (header.opcode != ns_opcode::ns_o_query) {
+        ALOGI("unsupported request opcode received");
+        return makeErrorResponse(&header, ns_rcode::ns_r_notimpl, response,
+                                 response_len);
+    }
+    if (header.questions.empty()) {
+        ALOGI("no questions present");
+        return makeErrorResponse(&header, ns_rcode::ns_r_formerr, response,
+                                 response_len);
+    }
+    if (!header.answers.empty()) {
+        ALOGI("already %zu answers present in query", header.answers.size());
+        return makeErrorResponse(&header, ns_rcode::ns_r_formerr, response,
+                                 response_len);
+    }
+    {
+        std::lock_guard<std::mutex> lock(queries_mutex_);
+        for (const DNSQuestion& question : header.questions) {
+            queries_.push_back(make_pair(question.qname.name,
+                                         ns_type(question.qtype)));
+        }
+    }
+
+    // Ignore requests with the preset probability.
+    auto constexpr bound = std::numeric_limits<unsigned>::max();
+    if (arc4random_uniform(bound) > bound*response_probability_) {
+        ALOGI("returning SRVFAIL in accordance with probability distribution");
+        return makeErrorResponse(&header, ns_rcode::ns_r_servfail, response,
+                                 response_len);
+    }
+
+    for (const DNSQuestion& question : header.questions) {
+        if (question.qclass != ns_class::ns_c_in &&
+            question.qclass != ns_class::ns_c_any) {
+            ALOGI("unsupported question class %u", question.qclass);
+            return makeErrorResponse(&header, ns_rcode::ns_r_notimpl, response,
+                                     response_len);
+        }
+        if (!addAnswerRecords(question, &header.answers)) {
+            return makeErrorResponse(&header, ns_rcode::ns_r_servfail, response,
+                                     response_len);
+        }
+    }
+    header.qr = true;
+    char* response_cur = header.write(response, response + *response_len);
+    if (response_cur == nullptr) {
+        return false;
+    }
+    *response_len = response_cur - response;
+    return true;
+}
+
+bool DNSResponder::addAnswerRecords(const DNSQuestion& question,
+                                    std::vector<DNSRecord>* answers) const {
+    auto it = mappings_.find(QueryKey(question.qname.name, question.qtype));
+    if (it == mappings_.end()) {
+        // TODO(imaipi): handle correctly
+        ALOGI("no mapping found for %s %s, lazily refusing to add an answer",
+            question.qname.name.c_str(), dnstype2str(question.qtype));
+        return true;
+    }
+    ALOGI("mapping found for %s %s: %s", question.qname.name.c_str(),
+        dnstype2str(question.qtype), it->second.c_str());
+    DNSRecord record;
+    record.name = question.qname;
+    record.rtype = question.qtype;
+    record.rclass = ns_class::ns_c_in;
+    record.ttl = 1;
+    if (question.qtype == ns_type::ns_t_a) {
+        record.rdata.resize(4);
+        if (inet_pton(AF_INET, it->second.c_str(), record.rdata.data()) != 1) {
+            ALOGI("inet_pton(AF_INET, %s) failed", it->second.c_str());
+            return false;
+        }
+    } else if (question.qtype == ns_type::ns_t_aaaa) {
+        record.rdata.resize(16);
+        if (inet_pton(AF_INET6, it->second.c_str(), record.rdata.data()) != 1) {
+            ALOGI("inet_pton(AF_INET6, %s) failed", it->second.c_str());
+            return false;
+        }
+    } else {
+        ALOGI("unhandled qtype %s", dnstype2str(question.qtype));
+        return false;
+    }
+    answers->push_back(std::move(record));
+    return true;
+}
+
+bool DNSResponder::makeErrorResponse(DNSHeader* header, ns_rcode rcode,
+                                     char* response, size_t* response_len)
+                                     const {
+    header->answers.clear();
+    header->authorities.clear();
+    header->additionals.clear();
+    header->rcode = rcode;
+    header->qr = true;
+    char* response_cur = header->write(response, response + *response_len);
+    if (response_cur == nullptr) return false;
+    *response_len = response_cur - response;
+    return true;
+}
+
+}  // namespace test
+
diff --git a/netd/tests/dns_responder.h b/netd/tests/dns_responder.h
new file mode 100644
index 0000000..4ed4bb2
--- /dev/null
+++ b/netd/tests/dns_responder.h
@@ -0,0 +1,132 @@
+/*
+ * 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 requied 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.
+ *
+ */
+
+#ifndef DNS_RESPONDER_H
+#define DNS_RESPONDER_H
+
+#include <arpa/nameser.h>
+
+#include <atomic>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <unordered_map>
+#include <vector>
+
+#include <android-base/thread_annotations.h>
+
+namespace test {
+
+struct DNSHeader;
+struct DNSQuestion;
+struct DNSRecord;
+
+/*
+ * Simple DNS responder, which replies to queries with the registered response
+ * for that type. Class is assumed to be IN. If no response is registered, the
+ * default error response code is returned.
+ */
+class DNSResponder {
+public:
+    DNSResponder(const char* listen_address, const char* listen_service,
+                 int poll_timeout_ms, uint16_t error_rcode,
+                 double response_probability);
+    ~DNSResponder();
+    void addMapping(const char* name, ns_type type, const char* addr);
+    void removeMapping(const char* name, ns_type type);
+    void setResponseProbability(double response_probability);
+    bool running() const;
+    bool startServer();
+    bool stopServer();
+    std::vector<std::pair<std::string, ns_type>> queries() const;
+    void clearQueries();
+
+private:
+    // Key used for accessing mappings.
+    struct QueryKey {
+        std::string name;
+        unsigned type;
+        QueryKey(std::string n, unsigned t) : name(n), type(t) {}
+        bool operator == (const QueryKey& o) const {
+            return name == o.name && type == o.type;
+        }
+        bool operator < (const QueryKey& o) const {
+            if (name < o.name) return true;
+            if (name > o.name) return false;
+            return type < o.type;
+        }
+    };
+
+    struct QueryKeyHash {
+        size_t operator() (const QueryKey& key) const {
+            return std::hash<std::string>()(key.name) +
+                   static_cast<size_t>(key.type);
+        }
+    };
+
+    // DNS request handler.
+    void requestHandler();
+
+    // Parses and generates a response message for incoming DNS requests.
+    // Returns false on parsing errors.
+    bool handleDNSRequest(const char* buffer, ssize_t buffer_len,
+                          char* response, size_t* response_len) const;
+
+    bool addAnswerRecords(const DNSQuestion& question,
+                          std::vector<DNSRecord>* answers) const;
+
+    bool generateErrorResponse(DNSHeader* header, ns_rcode rcode,
+                               char* response, size_t* response_len) const;
+    bool makeErrorResponse(DNSHeader* header, ns_rcode rcode, char* response,
+                           size_t* response_len) const;
+
+
+    // Address and service to listen on, currently limited to UDP.
+    const std::string listen_address_;
+    const std::string listen_service_;
+    // epoll_wait() timeout in ms.
+    const int poll_timeout_ms_;
+    // Error code to return for requests for an unknown name.
+    const uint16_t error_rcode_;
+    // Probability that a valid response is being sent instead of being sent
+    // instead of returning error_rcode_.
+    std::atomic<double> response_probability_;
+
+    // Mappings from (name, type) to registered response and the
+    // mutex protecting them.
+    std::unordered_map<QueryKey, std::string, QueryKeyHash> mappings_
+        GUARDED_BY(mappings_mutex_);
+    // TODO(imaipi): enable GUARDED_BY(mappings_mutex_);
+    std::mutex mappings_mutex_;
+    // Query names received so far and the corresponding mutex.
+    mutable std::vector<std::pair<std::string, ns_type>> queries_
+        GUARDED_BY(queries_mutex_);
+    mutable std::mutex queries_mutex_;
+    // Socket on which the server is listening.
+    int socket_;
+    // File descriptor for epoll.
+    int epoll_fd_;
+    // Signal for request handler termination.
+    std::atomic<bool> terminate_ GUARDED_BY(update_mutex_);
+    // Thread for handling incoming threads.
+    std::thread handler_thread_ GUARDED_BY(update_mutex_);
+    std::mutex update_mutex_;
+};
+
+}  // namespace test
+
+#endif  // DNS_RESPONDER_H
diff --git a/netd/tests/netd_test.cpp b/netd/tests/netd_test.cpp
new file mode 100644
index 0000000..97b91bd
--- /dev/null
+++ b/netd/tests/netd_test.cpp
@@ -0,0 +1,465 @@
+/*
+ * 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 requied 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 <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <cutils/sockets.h>
+#include <android-base/stringprintf.h>
+#include <private/android_filesystem_config.h>
+
+#include <thread>
+
+#include "NetdClient.h"
+
+#include <gtest/gtest.h>
+#define LOG_TAG "resolverTest"
+#include <utils/Log.h>
+#include <testUtil.h>
+
+#include "dns_responder.h"
+#include "resolv_params.h"
+
+using android::base::StringPrintf;
+using android::base::StringAppendF;
+
+// TODO: make this dynamic and stop depending on implementation details.
+#define TEST_OEM_NETWORK "oem29"
+#define TEST_NETID 30
+
+// The only response code used in this test, see
+// frameworks/base/services/java/com/android/server/NetworkManagementService.java
+// for others.
+static constexpr int ResponseCodeOK = 200;
+
+// Returns ResponseCode.
+int netdCommand(const char* sockname, const char* command) {
+    int sock = socket_local_client(sockname,
+                                   ANDROID_SOCKET_NAMESPACE_RESERVED,
+                                   SOCK_STREAM);
+    if (sock < 0) {
+        perror("Error connecting");
+        return -1;
+    }
+
+    // FrameworkListener expects the whole command in one read.
+    char buffer[256];
+    int nwritten = snprintf(buffer, sizeof(buffer), "0 %s", command);
+    if (write(sock, buffer, nwritten + 1) < 0) {
+        perror("Error sending netd command");
+        close(sock);
+        return -1;
+    }
+
+    int nread = read(sock, buffer, sizeof(buffer));
+    if (nread < 0) {
+        perror("Error reading response");
+        close(sock);
+        return -1;
+    }
+    close(sock);
+    return atoi(buffer);
+}
+
+
+bool expectNetdResult(int expected, const char* sockname, const char* format, ...) {
+    char command[256];
+    va_list args;
+    va_start(args, format);
+    vsnprintf(command, sizeof(command), format, args);
+    va_end(args);
+    int result = netdCommand(sockname, command);
+    EXPECT_EQ(expected, result) << command;
+    return (200 <= expected && expected < 300);
+}
+
+
+class ResolverTest : public ::testing::Test {
+protected:
+    virtual void SetUp() {
+        // Ensure resolutions go via proxy.
+        setenv("ANDROID_DNS_MODE", "", 1);
+        uid = getuid();
+        pid = getpid();
+        SetupOemNetwork();
+    }
+
+    virtual void TearDown() {
+        TearDownOemNetwork();
+        netdCommand("netd", "network destroy " TEST_OEM_NETWORK);
+    }
+
+    void SetupOemNetwork() {
+        netdCommand("netd", "network destroy " TEST_OEM_NETWORK);
+        if (expectNetdResult(ResponseCodeOK, "netd",
+                             "network create %s", TEST_OEM_NETWORK)) {
+            oemNetId = TEST_NETID;
+        }
+        setNetworkForProcess(oemNetId);
+        ASSERT_EQ((unsigned) oemNetId, getNetworkForProcess());
+    }
+
+    void TearDownOemNetwork() {
+        if (oemNetId != -1) {
+            expectNetdResult(ResponseCodeOK, "netd",
+                             "network destroy %s", TEST_OEM_NETWORK);
+        }
+    }
+
+    bool SetResolversForNetwork(const std::vector<std::string>& searchDomains,
+            const std::vector<std::string>& servers, const std::string& params) {
+        // No use case for empty domains / servers (yet).
+        if (searchDomains.empty() || servers.empty()) return false;
+
+        std::string cmd = StringPrintf("resolver setnetdns %d \"%s", oemNetId,
+                searchDomains[0].c_str());
+        for (size_t i = 1 ; i < searchDomains.size() ; ++i) {
+            cmd += " ";
+            cmd += searchDomains[i];
+        }
+        cmd += "\" ";
+
+        cmd += servers[0];
+        for (size_t i = 1 ; i < servers.size() ; ++i) {
+            cmd += " ";
+            cmd += servers[i];
+        }
+
+        if (!params.empty()) {
+            cmd += " --params \"";
+            cmd += params;
+            cmd += "\"";
+        }
+
+        int rv = netdCommand("netd", cmd.c_str());
+        std::cout << "command: '" << cmd << "', rv = " << rv << "\n";
+        if (rv != ResponseCodeOK) {
+            return false;
+        }
+        return true;
+    }
+
+    bool FlushCache() const {
+        return expectNetdResult(ResponseCodeOK, "netd", "resolver flushnet %d", oemNetId);
+    }
+
+    std::string ToString(const hostent* he) const {
+        if (he == nullptr) return "<null>";
+        char buffer[INET6_ADDRSTRLEN];
+        if (!inet_ntop(he->h_addrtype, he->h_addr_list[0], buffer, sizeof(buffer))) {
+            return "<invalid>";
+        }
+        return buffer;
+    }
+
+    std::string ToString(const addrinfo* ai) const {
+        if (!ai)
+            return "<null>";
+        for (const auto* aip = ai ; aip != nullptr ; aip = aip->ai_next) {
+            char host[NI_MAXHOST];
+            int rv = getnameinfo(aip->ai_addr, aip->ai_addrlen, host, sizeof(host), nullptr, 0,
+                    NI_NUMERICHOST);
+            if (rv != 0)
+                return gai_strerror(rv);
+            return host;
+        }
+        return "<invalid>";
+    }
+
+    size_t GetNumQueries(const test::DNSResponder& dns, const char* name) const {
+        auto queries = dns.queries();
+        size_t found = 0;
+        for (const auto& p : queries) {
+            std::cout << "query " << p.first << "\n";
+            if (p.first == name) {
+                ++found;
+            }
+        }
+        return found;
+    }
+
+    size_t GetNumQueriesForType(const test::DNSResponder& dns, ns_type type,
+            const char* name) const {
+        auto queries = dns.queries();
+        size_t found = 0;
+        for (const auto& p : queries) {
+            std::cout << "query " << p.first << "\n";
+            if (p.second == type && p.first == name) {
+                ++found;
+            }
+        }
+        return found;
+    }
+
+    int pid;
+    int uid;
+    int oemNetId = -1;
+    const std::vector<std::string> mDefaultSearchDomains = { "example.com" };
+    // <sample validity in s> <success threshold in percent> <min samples> <max samples>
+    const std::string mDefaultParams = "300 25 8 8";
+};
+
+TEST_F(ResolverTest, GetHostByName) {
+    const char* listen_addr = "127.0.0.3";
+    const char* listen_srv = "53";
+    const char* host_name = "hello.example.com.";
+    test::DNSResponder dns(listen_addr, listen_srv, 250, ns_rcode::ns_r_servfail, 1.0);
+    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.3");
+    ASSERT_TRUE(dns.startServer());
+    std::vector<std::string> servers = { listen_addr };
+    ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, servers, mDefaultParams));
+
+    dns.clearQueries();
+    const hostent* result = gethostbyname("hello");
+    EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(4, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ("1.2.3.3", ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+    dns.stopServer();
+}
+
+TEST_F(ResolverTest, GetAddrInfo) {
+    addrinfo* result = nullptr;
+
+    const char* listen_addr = "127.0.0.4";
+    const char* listen_srv = "53";
+    const char* host_name = "howdie.example.com.";
+    test::DNSResponder dns(listen_addr, listen_srv, 250,
+                           ns_rcode::ns_r_servfail, 1.0);
+    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.4");
+    dns.addMapping(host_name, ns_type::ns_t_aaaa, "::1.2.3.4");
+    ASSERT_TRUE(dns.startServer());
+    std::vector<std::string> servers = { listen_addr };
+    ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, servers, mDefaultParams));
+
+    dns.clearQueries();
+    EXPECT_EQ(0, getaddrinfo("howdie", nullptr, nullptr, &result));
+    size_t found = GetNumQueries(dns, host_name);
+    EXPECT_LE(1U, found);
+    // Could be A or AAAA
+    std::string result_str = ToString(result);
+    EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
+        << ", result_str='" << result_str << "'";
+    if (result) freeaddrinfo(result);
+    result = nullptr;
+
+    // Verify that it's cached.
+    size_t old_found = found;
+    EXPECT_EQ(0, getaddrinfo("howdie", nullptr, nullptr, &result));
+    found = GetNumQueries(dns, host_name);
+    EXPECT_LE(1U, found);
+    EXPECT_EQ(old_found, found);
+    result_str = ToString(result);
+    EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4")
+        << result_str;
+    if (result) freeaddrinfo(result);
+    result = nullptr;
+
+    // Verify that cache can be flushed.
+    dns.clearQueries();
+    ASSERT_TRUE(FlushCache());
+    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.44");
+    dns.addMapping(host_name, ns_type::ns_t_aaaa, "::1.2.3.44");
+
+    EXPECT_EQ(0, getaddrinfo("howdie", nullptr, nullptr, &result));
+    EXPECT_LE(1U, GetNumQueries(dns, host_name));
+    // Could be A or AAAA
+    result_str = ToString(result);
+    EXPECT_TRUE(result_str == "1.2.3.44" || result_str == "::1.2.3.44")
+        << ", result_str='" << result_str << "'";
+    if (result) freeaddrinfo(result);
+}
+
+TEST_F(ResolverTest, GetAddrInfoV4) {
+    addrinfo* result = nullptr;
+
+    const char* listen_addr = "127.0.0.5";
+    const char* listen_srv = "53";
+    const char* host_name = "hola.example.com.";
+    test::DNSResponder dns(listen_addr, listen_srv, 250,
+                           ns_rcode::ns_r_servfail, 1.0);
+    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.5");
+    ASSERT_TRUE(dns.startServer());
+    std::vector<std::string> servers = { listen_addr };
+    ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, servers, mDefaultParams));
+
+    addrinfo hints;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_INET;
+    EXPECT_EQ(0, getaddrinfo("hola", nullptr, &hints, &result));
+    EXPECT_EQ(1U, GetNumQueries(dns, host_name));
+    EXPECT_EQ("1.2.3.5", ToString(result));
+    if (result) freeaddrinfo(result);
+}
+
+TEST_F(ResolverTest, MultidomainResolution) {
+    std::vector<std::string> searchDomains = { "example1.com", "example2.com", "example3.com" };
+    const char* listen_addr = "127.0.0.6";
+    const char* listen_srv = "53";
+    const char* host_name = "nihao.example2.com.";
+    test::DNSResponder dns(listen_addr, listen_srv, 250,
+                           ns_rcode::ns_r_servfail, 1.0);
+    dns.addMapping(host_name, ns_type::ns_t_a, "1.2.3.3");
+    ASSERT_TRUE(dns.startServer());
+    std::vector<std::string> servers = { listen_addr };
+    ASSERT_TRUE(SetResolversForNetwork(searchDomains, servers, mDefaultParams));
+
+    dns.clearQueries();
+    const hostent* result = gethostbyname("nihao");
+    EXPECT_EQ(1U, GetNumQueriesForType(dns, ns_type::ns_t_a, host_name));
+    ASSERT_FALSE(result == nullptr);
+    ASSERT_EQ(4, result->h_length);
+    ASSERT_FALSE(result->h_addr_list[0] == nullptr);
+    EXPECT_EQ("1.2.3.3", ToString(result));
+    EXPECT_TRUE(result->h_addr_list[1] == nullptr);
+    dns.stopServer();
+}
+
+TEST_F(ResolverTest, GetAddrInfoV6_failing) {
+    addrinfo* result = nullptr;
+
+    const char* listen_addr0 = "127.0.0.7";
+    const char* listen_addr1 = "127.0.0.8";
+    const char* listen_srv = "53";
+    const char* host_name = "ohayou.example.com.";
+    test::DNSResponder dns0(listen_addr0, listen_srv, 250,
+                            ns_rcode::ns_r_servfail, 0.0);
+    test::DNSResponder dns1(listen_addr1, listen_srv, 250,
+                            ns_rcode::ns_r_servfail, 1.0);
+    dns0.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::5");
+    dns1.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::6");
+    ASSERT_TRUE(dns0.startServer());
+    ASSERT_TRUE(dns1.startServer());
+    std::vector<std::string> servers = { listen_addr0, listen_addr1 };
+    // <sample validity in s> <success threshold in percent> <min samples> <max samples>
+    unsigned sample_validity = 300;
+    int success_threshold = 25;
+    int sample_count = 8;
+    std::string params = StringPrintf("%u %d %d %d", sample_validity, success_threshold,
+            sample_count, sample_count);
+    ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, servers, params));
+
+    // Repeatedly perform resolutions for non-existing domains until MAXNSSAMPLES resolutions have
+    // reached the dns0, which is set to fail. No more requests should then arrive at that server
+    // for the next sample_lifetime seconds.
+    // TODO: This approach is implementation-dependent, change once metrics reporting is available.
+    addrinfo hints;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_INET6;
+    for (int i = 0 ; i < sample_count ; ++i) {
+        std::string domain = StringPrintf("nonexistent%d", i);
+        getaddrinfo(domain.c_str(), nullptr, &hints, &result);
+    }
+    // Due to 100% errors for all possible samples, the server should be ignored from now on and
+    // only the second one used for all following queries, until NSSAMPLE_VALIDITY is reached.
+    dns0.clearQueries();
+    dns1.clearQueries();
+    EXPECT_EQ(0, getaddrinfo("ohayou", nullptr, &hints, &result));
+    EXPECT_EQ(0U, GetNumQueries(dns0, host_name));
+    EXPECT_EQ(1U, GetNumQueries(dns1, host_name));
+    if (result) freeaddrinfo(result);
+}
+
+TEST_F(ResolverTest, GetAddrInfoV6_concurrent) {
+    const char* listen_addr0 = "127.0.0.9";
+    const char* listen_addr1 = "127.0.0.10";
+    const char* listen_addr2 = "127.0.0.11";
+    const char* listen_srv = "53";
+    const char* host_name = "konbanha.example.com.";
+    test::DNSResponder dns0(listen_addr0, listen_srv, 250,
+                            ns_rcode::ns_r_servfail, 1.0);
+    test::DNSResponder dns1(listen_addr1, listen_srv, 250,
+                            ns_rcode::ns_r_servfail, 1.0);
+    test::DNSResponder dns2(listen_addr2, listen_srv, 250,
+                            ns_rcode::ns_r_servfail, 1.0);
+    dns0.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::5");
+    dns1.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::6");
+    dns2.addMapping(host_name, ns_type::ns_t_aaaa, "2001:db8::7");
+    ASSERT_TRUE(dns0.startServer());
+    ASSERT_TRUE(dns1.startServer());
+    ASSERT_TRUE(dns2.startServer());
+    const std::vector<std::string> servers = { listen_addr0, listen_addr1, listen_addr2 };
+    std::vector<std::thread> threads(10);
+    for (std::thread& thread : threads) {
+       thread = std::thread([this, &servers, &dns0, &dns1, &dns2]() {
+            unsigned delay = arc4random_uniform(1*1000*1000); // <= 1s
+            usleep(delay);
+            std::vector<std::string> serverSubset;
+            for (const auto& server : servers) {
+                if (arc4random_uniform(2)) {
+                    serverSubset.push_back(server);
+                }
+            }
+            if (serverSubset.empty()) serverSubset = servers;
+            ASSERT_TRUE(SetResolversForNetwork(mDefaultSearchDomains, serverSubset,
+                    mDefaultParams));
+            addrinfo hints;
+            memset(&hints, 0, sizeof(hints));
+            hints.ai_family = AF_INET6;
+            addrinfo* result = nullptr;
+            int rv = getaddrinfo("konbanha", nullptr, &hints, &result);
+            EXPECT_EQ(0, rv) << "error [" << rv << "] " << gai_strerror(rv);
+        });
+    }
+    for (std::thread& thread : threads) {
+        thread.join();
+    }
+}
+
+TEST_F(ResolverTest, SearchPathChange) {
+    addrinfo* result = nullptr;
+
+    const char* listen_addr = "127.0.0.13";
+    const char* listen_srv = "53";
+    const char* host_name1 = "test13.domain1.org.";
+    const char* host_name2 = "test13.domain2.org.";
+    test::DNSResponder dns(listen_addr, listen_srv, 250,
+                           ns_rcode::ns_r_servfail, 1.0);
+    dns.addMapping(host_name1, ns_type::ns_t_aaaa, "2001:db8::13");
+    dns.addMapping(host_name2, ns_type::ns_t_aaaa, "2001:db8::1:13");
+    ASSERT_TRUE(dns.startServer());
+    std::vector<std::string> servers = { listen_addr };
+    std::vector<std::string> domains = { "domain1.org" };
+    ASSERT_TRUE(SetResolversForNetwork(domains, servers, mDefaultParams));
+
+    addrinfo hints;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_INET6;
+    EXPECT_EQ(0, getaddrinfo("test13", nullptr, &hints, &result));
+    EXPECT_EQ(1U, dns.queries().size());
+    EXPECT_EQ(1U, GetNumQueries(dns, host_name1));
+    EXPECT_EQ("2001:db8::13", ToString(result));
+    if (result) freeaddrinfo(result);
+
+    // Test that changing the domain search path on its own works.
+    domains = { "domain2.org" };
+    ASSERT_TRUE(SetResolversForNetwork(domains, servers, mDefaultParams));
+    dns.clearQueries();
+
+    EXPECT_EQ(0, getaddrinfo("test13", nullptr, &hints, &result));
+    EXPECT_EQ(1U, dns.queries().size());
+    EXPECT_EQ(1U, GetNumQueries(dns, host_name2));
+    EXPECT_EQ("2001:db8::1:13", ToString(result));
+    if (result) freeaddrinfo(result);
+}
diff --git a/netd/tests/sock_diag_test.cpp b/netd/tests/sock_diag_test.cpp
new file mode 100644
index 0000000..8ee9908
--- /dev/null
+++ b/netd/tests/sock_diag_test.cpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright 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.
+ *
+ * sock_diag_test.cpp - unit tests for SockDiag.cpp
+ */
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <linux/inet_diag.h>
+
+#include <gtest/gtest.h>
+
+#include "NetdConstants.h"
+#include "SockDiag.h"
+
+
+#define NUM_SOCKETS 500
+
+
+class SockDiagTest : public ::testing::Test {
+};
+
+uint16_t bindAndListen(int s) {
+    for (int i = 0; i < 10; i++) {
+        uint16_t port = 1024 + arc4random_uniform(0xffff - 1024);
+        sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_port = htons(port) };
+        if (bind(s, (sockaddr *) &sin6, sizeof(sin6)) == 0) {
+            listen(s, 1);
+            return port;
+        }
+    }
+    close(s);
+    return 0;
+}
+
+const char *tcpStateName(uint8_t state) {
+    static const char *states[] = {
+        "???",
+        "TCP_ESTABLISHED",
+        "TCP_SYN_SENT",
+        "TCP_SYN_RECV",
+        "TCP_FIN_WAIT1",
+        "TCP_FIN_WAIT2",
+        "TCP_TIME_WAIT",
+        "TCP_CLOSE",
+        "TCP_CLOSE_WAIT",
+        "TCP_LAST_ACK",
+        "TCP_LISTEN",
+        "TCP_CLOSING",
+        "TCP_NEW_SYN_RECV",
+    };
+    return states[(state < ARRAY_SIZE(states)) ? state : 0];
+}
+
+TEST_F(SockDiagTest, TestDump) {
+    int v4socket = socket(AF_INET, SOCK_STREAM, 0);
+    int v6socket = socket(AF_INET6, SOCK_STREAM, 0);
+    int listensocket = socket(AF_INET6, SOCK_STREAM, 0);
+    ASSERT_NE(-1, v4socket) << "Failed to open IPv4 socket";
+    ASSERT_NE(-1, v6socket) << "Failed to open IPv6 socket";
+    ASSERT_NE(-1, listensocket) << "Failed to open listen socket";
+
+    uint16_t port = bindAndListen(listensocket);
+    ASSERT_NE(0, port) << "Can't bind to server port";
+
+    // Connect to loopback.
+    sockaddr_in server4 = { .sin_family = AF_INET, .sin_port = htons(port) };
+    sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_port = htons(port) };
+    ASSERT_EQ(0, connect(v4socket, (sockaddr *) &server4, sizeof(server4)))
+        << "IPv4 connect failed: " << strerror(errno);
+    ASSERT_EQ(0, connect(v6socket, (sockaddr *) &server6, sizeof(server6)))
+        << "IPv6 connect failed: " << strerror(errno);
+
+    sockaddr_in6 client46, client6;
+    socklen_t clientlen = std::max(sizeof(client46), sizeof(client6));
+    int accepted4 = accept(listensocket, (sockaddr *) &client46, &clientlen);
+    int accepted6 = accept(listensocket, (sockaddr *) &client6, &clientlen);
+    ASSERT_NE(-1, accepted4);
+    ASSERT_NE(-1, accepted6);
+
+    int v4SocketsSeen = 0;
+    bool seenclient46 = false;
+    bool seenNull = false;
+    char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
+
+    fprintf(stderr, "Ports:\n  server=%d. client46=%d, client6=%d\n",
+            port, ntohs(client46.sin6_port), ntohs(client6.sin6_port));
+
+    auto checkIPv4Dump = [&] (uint8_t /* proto */, const inet_diag_msg *msg) {
+        if (msg == nullptr) {
+            EXPECT_FALSE(seenNull);
+            seenNull = true;
+            return 0;
+        }
+        EXPECT_EQ(htonl(INADDR_LOOPBACK), msg->id.idiag_src[0]);
+        v4SocketsSeen++;
+        seenclient46 |= (msg->id.idiag_sport == client46.sin6_port);
+        inet_ntop(AF_INET, msg->id.idiag_src, src, sizeof(src));
+        inet_ntop(AF_INET, msg->id.idiag_src, dst, sizeof(dst));
+        fprintf(stderr, "  v4 %s:%d -> %s:%d %s\n",
+                src, htons(msg->id.idiag_sport),
+                dst, htons(msg->id.idiag_dport),
+                tcpStateName(msg->idiag_state));
+        return 0;
+    };
+
+    int v6SocketsSeen = 0;
+    bool seenClient6 = false, seenServer46 = false, seenServer6 = false;
+
+    auto checkIPv6Dump = [&] (uint8_t /* proto */, const inet_diag_msg *msg) {
+        if (msg == nullptr) {
+            EXPECT_FALSE(seenNull);
+            seenNull = true;
+            return 0;
+        }
+        struct in6_addr *saddr = (struct in6_addr *) msg->id.idiag_src;
+        EXPECT_TRUE(
+            IN6_IS_ADDR_LOOPBACK(saddr) ||
+            (IN6_IS_ADDR_V4MAPPED(saddr) && saddr->s6_addr32[3] == htonl(INADDR_LOOPBACK)));
+        v6SocketsSeen++;
+        seenClient6 |= (msg->id.idiag_sport == client6.sin6_port);
+        seenServer46 |= (msg->id.idiag_sport == htons(port));
+        seenServer6 |= (msg->id.idiag_sport == htons(port));
+        inet_ntop(AF_INET6, msg->id.idiag_src, src, sizeof(src));
+        inet_ntop(AF_INET6, msg->id.idiag_src, dst, sizeof(dst));
+        fprintf(stderr, "  v6 [%s]:%d -> [%s]:%d %s\n",
+                src, htons(msg->id.idiag_sport),
+                dst, htons(msg->id.idiag_dport),
+                tcpStateName(msg->idiag_state));
+        return 0;
+    };
+
+    SockDiag sd;
+    ASSERT_TRUE(sd.open()) << "Failed to open SOCK_DIAG socket";
+
+    seenNull = false;
+    int ret = sd.sendDumpRequest(IPPROTO_TCP, AF_INET, "127.0.0.1");
+    ASSERT_EQ(0, ret) << "Failed to send IPv4 dump request: " << strerror(-ret);
+    fprintf(stderr, "Sent IPv4 dump\n");
+    sd.readDiagMsg(IPPROTO_TCP, checkIPv4Dump);
+    EXPECT_GE(v4SocketsSeen, 1);
+    EXPECT_TRUE(seenclient46);
+    EXPECT_FALSE(seenServer46);
+
+    seenNull = false;
+    ret = sd.sendDumpRequest(IPPROTO_TCP, AF_INET6, "127.0.0.1");
+    ASSERT_EQ(0, ret) << "Failed to send mapped dump request: " << strerror(-ret);
+    fprintf(stderr, "Sent mapped dump\n");
+    sd.readDiagMsg(IPPROTO_TCP, checkIPv6Dump);
+    EXPECT_TRUE(seenServer46);
+
+    seenNull = false;
+    ret = sd.sendDumpRequest(IPPROTO_TCP, AF_INET6, "::1");
+    ASSERT_EQ(0, ret) << "Failed to send IPv6 dump request: " << strerror(-ret);
+    fprintf(stderr, "Sent IPv6 dump\n");
+
+    sd.readDiagMsg(IPPROTO_TCP, checkIPv6Dump);
+    EXPECT_GE(v6SocketsSeen, 1);
+    EXPECT_TRUE(seenClient6);
+    EXPECT_TRUE(seenServer6);
+
+    close(v4socket);
+    close(v6socket);
+    close(listensocket);
+    close(accepted4);
+    close(accepted6);
+}
+
+TEST_F(SockDiagTest, TestMicroBenchmark) {
+    fprintf(stderr, "Benchmarking closing %d sockets\n", NUM_SOCKETS);
+
+    int listensocket = socket(AF_INET6, SOCK_STREAM, 0);
+    ASSERT_NE(-1, listensocket) << "Failed to open listen socket";
+
+    uint16_t port = bindAndListen(listensocket);
+    ASSERT_NE(0, port) << "Can't bind to server port";
+    sockaddr_in6 server = { .sin6_family = AF_INET6, .sin6_port = htons(port) };
+
+    using ms = std::chrono::duration<float, std::ratio<1, 1000>>;
+
+    int clientsockets[NUM_SOCKETS], serversockets[NUM_SOCKETS];
+    uint16_t clientports[NUM_SOCKETS];
+    sockaddr_in6 client;
+    socklen_t clientlen;
+
+    auto start = std::chrono::steady_clock::now();
+    for (int i = 0; i < NUM_SOCKETS; i++) {
+        int s = socket(AF_INET6, SOCK_STREAM, 0);
+        clientlen = sizeof(client);
+        ASSERT_EQ(0, connect(s, (sockaddr *) &server, sizeof(server)))
+            << "Connecting socket " << i << " failed " << strerror(errno);
+        serversockets[i] = accept(listensocket, (sockaddr *) &client, &clientlen);
+        ASSERT_NE(-1, serversockets[i])
+            << "Accepting socket " << i << " failed " << strerror(errno);
+        clientports[i] = client.sin6_port;
+        clientsockets[i] = s;
+    }
+    fprintf(stderr, "  Connecting: %6.1f ms\n",
+            std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());
+
+    SockDiag sd;
+    ASSERT_TRUE(sd.open()) << "Failed to open SOCK_DIAG socket";
+
+    start = std::chrono::steady_clock::now();
+    int ret = sd.destroySockets("::1");
+    EXPECT_LE(0, ret) << ": Failed to destroy sockets on ::1: " << strerror(-ret);
+    fprintf(stderr, "  Destroying: %6.1f ms\n",
+            std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());
+
+    int err;
+    start = std::chrono::steady_clock::now();
+    for (int i = 0; i < NUM_SOCKETS; i++) {
+        ret = send(clientsockets[i], "foo", sizeof("foo"), 0);
+        err = errno;
+        EXPECT_EQ(-1, ret) << "Client socket " << i << " not closed";
+        if (ret == -1) {
+            // Since we're connected to ourselves, the error might be ECONNABORTED (if we destroyed
+            // the socket) or ECONNRESET (if the other end was destroyed and sent a RST).
+            EXPECT_TRUE(errno == ECONNABORTED || errno == ECONNRESET)
+                << "Client socket: unexpected error: " << strerror(errno);
+        }
+
+        ret = send(serversockets[i], "foo", sizeof("foo"), 0);
+        err = errno;
+        EXPECT_EQ(-1, ret) << "Server socket " << i << " not closed";
+        if (ret == -1) {
+            EXPECT_TRUE(errno == ECONNABORTED || errno == ECONNRESET)
+                << "Server socket: unexpected error: " << strerror(errno);
+        }
+    }
+    fprintf(stderr, "   Verifying: %6.1f ms\n",
+            std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());
+
+
+
+    start = std::chrono::steady_clock::now();
+    for (int i = 0; i < NUM_SOCKETS; i++) {
+        close(clientsockets[i]);
+        close(serversockets[i]);
+    }
+    fprintf(stderr, "     Closing: %6.1f ms\n",
+            std::chrono::duration_cast<ms>(std::chrono::steady_clock::now() - start).count());
+
+    close(listensocket);
+}
