Clean up prior version of WiFi

BUG: 77809394
Test: Local build and boot
Change-Id: I19d213a15e021e125ad7cf662c4b3fe456782175
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();
-}