diff --git a/common/commands/Android.bp b/common/commands/Android.bp
index b674475..4392d9d 100644
--- a/common/commands/Android.bp
+++ b/common/commands/Android.bp
@@ -14,6 +14,5 @@
 // limitations under the License.
 
 subdirs = [
-    "wificlient",
     "wifi_relay",
 ]
diff --git a/common/commands/wificlient/Android.bp b/common/commands/wificlient/Android.bp
deleted file mode 100644
index 7952a1f..0000000
--- a/common/commands/wificlient/Android.bp
+++ /dev/null
@@ -1,34 +0,0 @@
-cc_binary {
-    name: "wificlient",
-    srcs: [
-        "main.cc",
-    ],
-    shared_libs: [
-        "libbase",
-        "vsoc_lib",
-        "libcuttlefish_fs",
-        "cuttlefish_auto_resources",
-        "liblog",
-        "libnl",
-    ],
-    static_libs: [
-        "libgflags",
-    ],
-    header_libs: [
-        "cuttlefish_glog",
-    ],
-    target: {
-        host: {
-            static_libs: [
-                "libcuttlefish_wifi",
-                "libcuttlefish_host_config",
-            ],
-        },
-        android: {
-            static_libs: [
-                "libcuttlefish_wifi",
-            ],
-        }
-    },
-    defaults: ["cuttlefish_host_and_guest", "cuttlefish_native_isa"]
-}
diff --git a/common/commands/wificlient/main.cc b/common/commands/wificlient/main.cc
deleted file mode 100644
index 1b6736b..0000000
--- a/common/commands/wificlient/main.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gflags/gflags.h>
-#include <glog/logging.h>
-
-#include "common/libs/wifi/netlink.h"
-#include "common/libs/wifi/packet_switch.h"
-#include "common/libs/wifi/virtual_wifi.h"
-
-DEFINE_string(router, "cvd-wifirouter", "Path to WIFI Router Unix socket.");
-DEFINE_string(iface, "cf-wlan0", "Name of the WLAN interface to create.");
-DEFINE_string(macaddr, "00:43:56:44:80:01", "MAC address for new interface");
-DEFINE_string(wifirouter_socket, "cvd-wifirouter",
-              "Name of the wifirouter unix domain socket.");
-
-int main(int argc, char* argv[]) {
-  gflags::ParseCommandLineFlags(&argc, &argv, true);
-
-  std::unique_ptr<cvd::Netlink> nl(new cvd::Netlink(FLAGS_wifirouter_socket));
-  if (!nl->Init()) {
-    LOG(ERROR) << "Could not initialize netlink.";
-    exit(1);
-  }
-
-  cvd::PacketSwitch pktswitch(nl.get());
-  if (!pktswitch.Init()) {
-    LOG(ERROR) << "Could not initialize packet switch.";
-    exit(1);
-  }
-
-  std::unique_ptr<cvd::VirtualWIFI> radio(
-      new cvd::VirtualWIFI(nl.get(), FLAGS_iface, FLAGS_macaddr));
-  if (!radio->Init()) {
-    LOG(ERROR) << "Could not create radio.";
-    exit(1);
-  }
-
-  pktswitch.Start();
-
-  pause();
-}
diff --git a/guest/commands/Android.bp b/guest/commands/Android.bp
index cbd09e8..2f0e565 100644
--- a/guest/commands/Android.bp
+++ b/guest/commands/Android.bp
@@ -13,7 +13,3 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-subdirs = [
-    "wifirouter",
-]
-
diff --git a/guest/commands/wifirouter/Android.bp b/guest/commands/wifirouter/Android.bp
deleted file mode 100644
index ed5d930..0000000
--- a/guest/commands/wifirouter/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-cc_binary {
-    name: "wifirouter",
-    srcs: ["router.cc"],
-    static_libs: [
-        "libbase",
-        "libgflags",
-        "libnl",
-    ],
-    shared_libs: [
-        "liblog",
-    ],
-    header_libs: [
-        "cuttlefish_common_headers",
-        "cuttlefish_glog",
-    ],
-    defaults: ["cuttlefish_base"],
-}
-
diff --git a/guest/commands/wifirouter/router.cc b/guest/commands/wifirouter/router.cc
deleted file mode 100644
index 805b2fb..0000000
--- a/guest/commands/wifirouter/router.cc
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "common/libs/wifi/router.h"
-
-#include <cerrno>
-#include <cstddef>
-#include <iomanip>
-#include <map>
-#include <memory>
-#include <set>
-
-#include <gflags/gflags.h>
-#include <glog/logging.h>
-#include <netinet/in.h>
-#include <linux/if_ether.h>
-#include <linux/netdevice.h>
-#include <netlink/genl/ctrl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/genl.h>
-#include <netlink/netlink.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-DEFINE_string(socket_name, "cvd-wifirouter",
-              "Name of the unix-domain socket providing access for routing. "
-              "Socket will be created in abstract namespace.");
-DEFINE_bool(use_fixed_addresses, false,
-            "Specify to use hard-coded WIFI addresses issued by MAC80211 HWSIM."
-            " This is relevant for systems, where mac address update is not"
-            " reflected in mac80211_hwsim module.");
-DEFINE_bool(log_broadcast_frames, false, "Specify to log broadcast frames.");
-
-namespace cvd {
-// Copied out of mac80211_hwsim.h header.
-constexpr int HWSIM_CMD_REGISTER = 1;
-constexpr int HWSIM_CMD_FRAME = 2;
-constexpr int HWSIM_CMD_TX_INFO_FRAME __unused = 3;
-
-constexpr int HWSIM_TX_CTL_REQ_TX_STATUS __unused = 1;
-constexpr int HWSIM_TX_CTL_NO_ACK __unused = 2;
-constexpr int HWSIM_TX_STAT_ACK __unused = 4;
-
-constexpr int HWSIM_ATTR_ADDR_RECEIVER = 1;
-constexpr int HWSIM_ATTR_ADDR_TRANSMITTER = 2;
-constexpr int HWSIM_ATTR_FRAME = 3;
-constexpr int HWSIM_ATTR_FLAGS __unused = 4;
-constexpr int HWSIM_ATTR_RX_RATE = 5;
-constexpr int HWSIM_ATTR_SIGNAL = 6;
-constexpr int HWSIM_ATTR_TX_INFO __unused = 7;
-constexpr int HWSIM_ATTR_COOKIE __unused = 8;
-constexpr int HWSIM_ATTR_MAX = 19;
-
-// Name of the WIFI SIM Netlink Family.
-constexpr char kWifiSimFamilyName[] = "MAC80211_HWSIM";
-const int kMaxSupportedPacketSize = getpagesize();
-
-constexpr int kDefaultSignalLevel = -24;
-
-using MACAddress = uint8_t[6];
-
-struct IEEE80211Hdr {
-  uint16_t frame_control;
-  uint16_t duration_id;
-  MACAddress destination;
-  MACAddress source;
-  MACAddress bssid;
-  uint16_t seq;
-
-  bool IsBroadcast() const;
-} __attribute__((packed));
-
-std::ostream& operator<<(std::ostream& out, const MACAddress& addr) {
-  out << std::hex
-      << std::setfill('0') << std::setw(2) << int(addr[0]) << ':'
-      << std::setfill('0') << std::setw(2) << int(addr[1]) << ':'
-      << std::setfill('0') << std::setw(2) << int(addr[2]) << ':'
-      << std::setfill('0') << std::setw(2) << int(addr[3]) << ':'
-      << std::setfill('0') << std::setw(2) << int(addr[4]) << ':'
-      << std::setfill('0') << std::setw(2) << int(addr[5]) << std::dec;
-
-  return out;
-}
-
-std::ostream& operator<<(std::ostream& out, const IEEE80211Hdr& frm) {
-  out << "IEEE80211Hdr{ Type=" << std::hex << std::setw(4) << std::setfill('0')
-      << frm.frame_control << std::dec
-      << " From=" << frm.source
-      << " To=" << frm.destination << " Via=" << frm.bssid << " }";
-  return out;
-}
-
-bool IEEE80211Hdr::IsBroadcast() const {
-  return (destination[0] & destination[1] & destination[2] & destination[3] &
-      destination[4] & destination[5]) == 0xff;
-}
-
-class WifiRouter {
- public:
-  using RadioID = int32_t;
-  using Radio = struct {
-    RadioID id;
-    uint8_t mac[ETH_ALEN];
-  };
-  using RadioToClientsTable = std::multimap<RadioID, int>;
-  using ClientToRadiosTable = std::multimap<int, Radio>;
-  using MacAddrToRadioIDTable = std::map<uint64_t, RadioID>;
-  const RadioID RadioID_Invalid = -1;
-
-  WifiRouter() : sock_(nullptr, nl_socket_free) {}
-  ~WifiRouter() = default;
-
-  void Init();
-  void ServerLoop();
-
- private:
-  void AddRadioID(int client, RadioID radio_id, const void* macaddr);
-  RadioID GetRadioID(const void* macaddr);
-  void CreateWifiRouterServerSocket();
-
-  void RegisterForHWSimNotifications();
-  void RouteWIFIPacket();
-
-  void AcceptNewClient();
-  bool HandleClientMessage(int client);
-  void RemoveClient(int client);
-
-  std::unique_ptr<nl_sock, void (*)(nl_sock*)> sock_;
-  int server_fd_ = 0;
-  int mac80211_family_ = 0;
-  ClientToRadiosTable registered_clients_;
-  RadioToClientsTable registered_addresses_;
-  MacAddrToRadioIDTable known_addresses_;
-};
-
-void WifiRouter::AddRadioID(int client, RadioID radio_id, const void* macaddr) {
-  const uint8_t* addr_bytes = reinterpret_cast<const uint8_t*>(macaddr);
-  uint64_t mac;
-  Radio r{radio_id, {}};
-
-  mac = (addr_bytes[0] << 24) | (addr_bytes[1] << 16) | (addr_bytes[2] >> 8) |
-      addr_bytes[3];
-  mac <<= 16;
-  mac |= (addr_bytes[4] << 8) | addr_bytes[5];
-
-  known_addresses_[mac] = radio_id;
-  // Add two MAC addresses registered internally by MAC80211_HWSIM.
-  mac = 0x020000000000ull;
-  mac |= (radio_id << 8);
-  known_addresses_[mac] = radio_id;
-
-  mac |= 0x400000000000ull;
-  known_addresses_[mac] = radio_id;
-
-  if (FLAGS_use_fixed_addresses) {
-    r.mac[0] = mac >> 40;
-    r.mac[1] = mac >> 32;
-    r.mac[2] = mac >> 24;
-    r.mac[3] = mac >> 16;
-    r.mac[4] = mac >> 8;
-    r.mac[5] = mac;
-  } else {
-    memcpy(r.mac, macaddr, ETH_ALEN);
-  }
-  registered_addresses_.emplace(radio_id, client);
-  registered_clients_.emplace(client, r);
-}
-
-WifiRouter::RadioID WifiRouter::GetRadioID(const void* macaddr) {
-  const uint8_t* addr_bytes = reinterpret_cast<const uint8_t*>(macaddr);
-  uint64_t mac;
-
-  mac = (addr_bytes[0] << 24) | (addr_bytes[1] << 16) | (addr_bytes[2] >> 8) |
-      addr_bytes[3];
-  mac <<= 16;
-  mac |= (addr_bytes[4] << 8) | addr_bytes[5];
-
-  auto iter = known_addresses_.find(mac);
-  if (iter == known_addresses_.end()) return RadioID_Invalid;
-  return iter->second;
-}
-
-void WifiRouter::Init() {
-  CreateWifiRouterServerSocket();
-  RegisterForHWSimNotifications();
-}
-
-// Enable asynchronous notifications from MAC80211_HWSIM.
-// - `sock` is a valid netlink socket connected to NETLINK_GENERIC,
-// - `family` is MAC80211_HWSIM genl family number.
-//
-// Upon failure, this function will terminate execution of the program.
-void WifiRouter::RegisterForHWSimNotifications() {
-  sock_.reset(nl_socket_alloc());
-
-  // Disable sequence number checks. Occasional "Message sequence number
-  // mismatch" errors were observed, despite netlink allocating sequence numbers
-  // itself.
-  nl_socket_disable_seq_check(sock_.get());
-
-  auto res = nl_connect(sock_.get(), NETLINK_GENERIC);
-  if (res < 0) {
-    LOG(ERROR) << "Could not connect to netlink generic: " << nl_geterror(res);
-    exit(1);
-  }
-
-  mac80211_family_ = genl_ctrl_resolve(sock_.get(), kWifiSimFamilyName);
-  if (mac80211_family_ <= 0) {
-    LOG(ERROR) << "Could not find MAC80211 HWSIM. Please make sure module "
-               << "'mac80211_hwsim' is loaded on your system.";
-    exit(1);
-  }
-
-  std::unique_ptr<nl_msg, void (*)(nl_msg*)> msg(
-      nlmsg_alloc(), [](nl_msg* m) { nlmsg_free(m); });
-  genlmsg_put(msg.get(), NL_AUTO_PID, NL_AUTO_SEQ, mac80211_family_, 0,
-              NLM_F_REQUEST, HWSIM_CMD_REGISTER, 0);
-  nl_send_auto(sock_.get(), msg.get());
-
-  res = nl_wait_for_ack(sock_.get());
-  if (res < 0) {
-    LOG(ERROR) << "Could not register for notifications: " << nl_geterror(res);
-    exit(1);
-  }
-}
-
-// Create and configure WIFI Router server socket.
-// This function is guaranteed to success. If at any point an error is detected,
-// the function will terminate execution of the program.
-void WifiRouter::CreateWifiRouterServerSocket() {
-  server_fd_ = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-  if (server_fd_ < 0) {
-    LOG(ERROR) << "Could not create unix socket: " << strerror(-errno);
-    exit(1);
-  }
-
-  sockaddr_un addr{};
-  addr.sun_family = AF_UNIX;
-  auto len = std::min(sizeof(addr.sun_path) - 2, FLAGS_socket_name.size());
-  strncpy(&addr.sun_path[1], FLAGS_socket_name.c_str(), len);
-  len += offsetof(sockaddr_un, sun_path) + 1;  // include heading \0 byte.
-  auto res = bind(server_fd_, reinterpret_cast<sockaddr*>(&addr), len);
-
-  if (res < 0) {
-    LOG(ERROR) << "Could not bind unix socket: " << strerror(-errno);
-    exit(1);
-  }
-
-  listen(server_fd_, 4);
-}
-
-// Accept new WIFI Router client. When successful, client will be placed in
-// clients table.
-void WifiRouter::AcceptNewClient() {
-  auto client = accept(server_fd_, nullptr, nullptr);
-  if (client < 0) {
-    LOG(ERROR) << "Could not accept client: " << strerror(-errno);
-    return;
-  }
-
-  registered_clients_.insert({client, {RadioID_Invalid, {}}});
-  LOG(INFO) << "Client " << client << " added.";
-}
-
-// Disconnect and remove client from list of registered clients and recipients
-// of WLAN traffic.
-void WifiRouter::RemoveClient(int client) {
-  close(client);
-
-  registered_clients_.erase(client);
-
-  for (auto iter = registered_addresses_.begin();
-       iter != registered_addresses_.end();) {
-    if (iter->second == client) {
-      iter = registered_addresses_.erase(iter);
-    } else {
-      ++iter;
-    }
-  }
-  LOG(INFO) << "Client " << client << " removed.";
-}
-
-// Read MAC80211HWSIM packet, find the originating MAC address and redirect it
-// to proper sink.
-void WifiRouter::RouteWIFIPacket() {
-  sockaddr_nl tmp;
-  uint8_t* buf;
-
-  const auto len = nl_recv(sock_.get(), &tmp, &buf, nullptr);
-  if (len < 0) {
-    LOG(ERROR) << "Could not read from netlink: " << nl_geterror(len);
-    return;
-  }
-
-  std::unique_ptr<nlmsghdr, void (*)(nlmsghdr*)> msg(
-      reinterpret_cast<nlmsghdr*>(buf), [](nlmsghdr* m) { free(m); });
-
-  // Discard messages that originate from anything else than MAC80211_HWSIM.
-  if (msg->nlmsg_type != mac80211_family_) return;
-
-  genlmsghdr* gmsg = reinterpret_cast<genlmsghdr*>(nlmsg_data(msg.get()));
-  if (gmsg->cmd != HWSIM_CMD_FRAME) {
-    LOG(INFO) << "Discarding non-FRAME message.";
-    return;
-  }
-
-  std::unique_ptr<nl_msg, void (*)(nl_msg*)> rep(
-      nlmsg_alloc(), [](nl_msg* m) { nlmsg_free(m); });
-  genlmsg_put(rep.get(), 0, 0, 0, 0, 0, WIFIROUTER_CMD_NOTIFY, 0);
-
-  // Note, this is generic netlink message, and uses different parsing
-  // technique.
-  nlattr* attrs[HWSIM_ATTR_MAX + 1];
-  if (genlmsg_parse(msg.get(), 0, attrs, HWSIM_ATTR_MAX, nullptr)) return;
-
-  auto ieee80211hdr = reinterpret_cast<IEEE80211Hdr*>(nla_data(attrs[HWSIM_ATTR_FRAME]));
-  if (!ieee80211hdr->IsBroadcast() || FLAGS_log_broadcast_frames) {
-    LOG(INFO) << "SND " << *ieee80211hdr;
-  }
-
-  std::set<int> pending_removals;
-  auto addr = attrs[HWSIM_ATTR_ADDR_TRANSMITTER];
-  if (addr != nullptr) {
-    nla_put_u32(rep.get(), WIFIROUTER_ATTR_HWSIM_ID,
-                GetRadioID(nla_data(addr)));
-    nla_put(rep.get(), WIFIROUTER_ATTR_PACKET, len, buf);
-    auto hdr = nlmsg_hdr(rep.get());
-
-    auto key = GetRadioID(nla_data(attrs[HWSIM_ATTR_ADDR_TRANSMITTER]));
-    for (auto it = registered_addresses_.find(key);
-         it != registered_addresses_.end() && it->first == key; ++it) {
-      auto num_written = send(it->second, hdr, hdr->nlmsg_len, MSG_NOSIGNAL);
-      if (num_written != static_cast<int64_t>(hdr->nlmsg_len)) {
-        pending_removals.insert(it->second);
-      }
-    }
-
-    for (auto client : pending_removals) RemoveClient(client);
-  }
-}
-
-bool WifiRouter::HandleClientMessage(int client) {
-  std::unique_ptr<nlmsghdr, void (*)(nlmsghdr*)> msg(
-      reinterpret_cast<nlmsghdr*>(malloc(kMaxSupportedPacketSize)),
-      [](nlmsghdr* h) { free(h); });
-  ssize_t size = recv(client, msg.get(), kMaxSupportedPacketSize, 0);
-
-  // Invalid message or no data -> client invalid or disconnected.
-  if (size == 0 || size != static_cast<ssize_t>(msg->nlmsg_len) ||
-      size < static_cast<ssize_t>(sizeof(nlmsghdr))) {
-    return false;
-  }
-
-  int result = -EINVAL;
-  genlmsghdr* ghdr = reinterpret_cast<genlmsghdr*>(nlmsg_data(msg.get()));
-
-  nlattr* attrs[WIFIROUTER_ATTR_MAX];
-  if (nlmsg_parse(msg.get(), sizeof(genlmsghdr), attrs, WIFIROUTER_ATTR_MAX - 1,
-                  nullptr))
-    return false;
-
-  switch (ghdr->cmd) {
-    case WIFIROUTER_CMD_REGISTER:
-      if (attrs[WIFIROUTER_ATTR_HWSIM_ID] != nullptr) {
-        int simid = nla_get_u32(attrs[WIFIROUTER_ATTR_HWSIM_ID]);
-        uint8_t* simaddr = reinterpret_cast<uint8_t*>(
-            nla_data(attrs[WIFIROUTER_ATTR_HWSIM_ADDR]));
-
-        AddRadioID(client, simid, simaddr);
-        // This is unfortunate, but it is a bug in mac80211_hwsim stack.
-        // Apparently, the imperfect medium will not receive notifications for
-        // newly created wifi interfaces. How about that...
-        RegisterForHWSimNotifications();
-        result = 0;
-      }
-      break;
-
-    case WIFIROUTER_CMD_SEND:
-      if (attrs[WIFIROUTER_ATTR_PACKET] != nullptr) {
-        std::unique_ptr<nl_msg, void (*)(nl_msg*)> frame(
-            nlmsg_convert(reinterpret_cast<nlmsghdr*>(
-                nla_data(attrs[WIFIROUTER_ATTR_PACKET]))),
-            nlmsg_free);
-
-        // Netlink is not smart enough to re-alloc.
-        nlmsg_expand(frame.get(), nlmsg_get_max_size(frame.get()) + 64);
-
-        auto hdr = nlmsg_hdr(frame.get());
-        hdr->nlmsg_type = mac80211_family_;
-        hdr->nlmsg_flags = NLM_F_REQUEST;
-
-        auto pktdata = nlmsg_find_attr(nlmsg_hdr(frame.get()),
-                                     sizeof(genlmsghdr),
-                                     HWSIM_ATTR_FRAME);
-        auto ieee80211hdr = reinterpret_cast<IEEE80211Hdr*>(nla_data(pktdata));
-        if (!ieee80211hdr->IsBroadcast() || FLAGS_log_broadcast_frames) {
-          LOG(INFO) << "RCV " << *ieee80211hdr;
-        }
-
-        auto receiver =
-            nla_reserve(frame.get(), HWSIM_ATTR_ADDR_RECEIVER, ETH_ALEN);
-        if (nla_put_u32(frame.get(), HWSIM_ATTR_RX_RATE, 1) ||
-            nla_put_u32(frame.get(), HWSIM_ATTR_SIGNAL, kDefaultSignalLevel) ||
-            !receiver) {
-          LOG(ERROR) << "Could not add netlink attribute: buffer too short.";
-        } else {
-          uint8_t* macaddr = reinterpret_cast<uint8_t*>(nla_data(receiver));
-          for (auto iter = registered_clients_.find(client);
-               iter->first == client; ++iter) {
-            if (iter->second.id == RadioID_Invalid) continue;
-            memcpy(macaddr, iter->second.mac, ETH_ALEN);
-            hdr->nlmsg_seq = NL_AUTO_SEQ;
-            hdr->nlmsg_pid = NL_AUTO_PID;
-            nl_send_auto(sock_.get(), frame.get());
-            auto res = nl_wait_for_ack(sock_.get());
-            if (res) {
-              LOG(INFO) << "Packet send from " << client << " to "
-                        << iter->second.id << " result: " << nl_geterror(-res);
-            }
-          }
-        }
-        result = 0;
-      }
-      break;
-
-    default:
-      break;
-  }
-
-  nlmsgerr err{.error = result};
-  std::unique_ptr<nl_msg, void (*)(nl_msg*)> rsp(nlmsg_alloc(), nlmsg_free);
-  nlmsg_put(rsp.get(), msg->nlmsg_pid, msg->nlmsg_seq, NLMSG_ERROR, 0, 0);
-  nlmsg_append(rsp.get(), &err, sizeof(err), 0);
-  auto hdr = nlmsg_hdr(rsp.get());
-  if (send(client, hdr, hdr->nlmsg_len, MSG_NOSIGNAL) !=
-      static_cast<int64_t>(hdr->nlmsg_len)) {
-    return false;
-  }
-  return true;
-}
-
-// Process incoming requests from netlink, server or clients.
-void WifiRouter::ServerLoop() {
-  while (true) {
-    auto max_fd = 0;
-    fd_set reads{};
-
-    auto fdset = [&max_fd, &reads](int fd) {
-      FD_SET(fd, &reads);
-      max_fd = std::max(max_fd, fd);
-    };
-
-    fdset(server_fd_);
-    fdset(nl_socket_get_fd(sock_.get()));
-    for (const auto& client : registered_clients_) fdset(client.first);
-
-    if (select(max_fd + 1, &reads, nullptr, nullptr, nullptr) <= 0) continue;
-
-    if (FD_ISSET(server_fd_, &reads)) AcceptNewClient();
-    if (FD_ISSET(nl_socket_get_fd(sock_.get()), &reads)) RouteWIFIPacket();
-
-    std::set<int> rogue_clients;
-    // Process any client messages left. Drop any client that is no longer
-    // talking with us.
-    for (auto cfd : registered_clients_) {
-      // Is our client sending us data?
-      if (FD_ISSET(cfd.first, &reads)) {
-        if (!HandleClientMessage(cfd.first)) rogue_clients.insert(cfd.first);
-        // Note: we iterate over multimap.
-        FD_CLR(cfd.first, &reads);
-      }
-    }
-
-    for (auto client : rogue_clients) RemoveClient(client);
-  }
-}
-
-}  // namespace cvd
-
-int main(int argc, char* argv[]) {
-  using namespace cvd;
-  google::ParseCommandLineFlags(&argc, &argv, true);
-#if !defined(ANDROID)
-  // We should check for legitimate google logging here.
-  google::InitGoogleLogging(argv[0]);
-  google::InstallFailureSignalHandler();
-#endif
-
-  WifiRouter r;
-  r.Init();
-  r.ServerLoop();
-}
