arc: Move platform2/arc/network/ to platform2/patchpanel

Next step in the arc-networkd -> patchpanel rename, this patch moves the
location of the code.

BUG=b:151879931
TEST=units,flashed image to atlas
TEST=tasts arc.PlayStore, crostini.LaunchTerminal.download

Change-Id: I1b5cf8d670e1631d46f6449b725395157bf88dde
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2115863
Tested-by: Garrick Evans <garrick@chromium.org>
Commit-Queue: Garrick Evans <garrick@chromium.org>
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Eric Caruso <ejcaruso@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
diff --git a/patchpanel/subnet.cc b/patchpanel/subnet.cc
new file mode 100644
index 0000000..8fa6f4b
--- /dev/null
+++ b/patchpanel/subnet.cc
@@ -0,0 +1,144 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "patchpanel/subnet.h"
+
+#include <arpa/inet.h>
+
+#include <string>
+#include <utility>
+
+#include <base/bind.h>
+#include <base/logging.h>
+
+#include "patchpanel/net_util.h"
+
+namespace {
+// Returns the offset from the base address given in network-byte order for
+// the address given in network-byte order, or 0 if the second address is
+// lower than the base address. Returns the offset in host-byte order.
+uint32_t OffsetFromBaseAddress(uint32_t base_no, uint32_t addr_no) {
+  if (ntohl(addr_no) < ntohl(base_no))
+    return 0;
+  return ntohl(addr_no) - ntohl(base_no);
+}
+// Adds a positive offset given in host order to the address given in
+// network byte order. Returns the address in network-byte order.
+uint32_t AddOffset(uint32_t addr_no, uint32_t offset_ho) {
+  return htonl(ntohl(addr_no) + offset_ho);
+}
+}  // namespace
+
+namespace patchpanel {
+
+SubnetAddress::SubnetAddress(uint32_t addr,
+                             uint32_t prefix_length,
+                             base::Closure release_cb)
+    : addr_(addr),
+      prefix_length_(prefix_length),
+      release_cb_(std::move(release_cb)) {}
+
+SubnetAddress::~SubnetAddress() {
+  release_cb_.Run();
+}
+
+uint32_t SubnetAddress::Address() const {
+  return addr_;
+}
+
+std::string SubnetAddress::ToCidrString() const {
+  return IPv4AddressToCidrString(addr_, prefix_length_);
+}
+
+std::string SubnetAddress::ToIPv4String() const {
+  return IPv4AddressToString(addr_);
+}
+
+uint32_t SubnetAddress::Netmask() const {
+  return Ipv4Netmask(prefix_length_);
+}
+
+Subnet::Subnet(uint32_t base_addr,
+               uint32_t prefix_length,
+               base::Closure release_cb)
+    : base_addr_(base_addr),
+      prefix_length_(prefix_length),
+      release_cb_(std::move(release_cb)),
+      weak_factory_(this) {
+  CHECK_LT(prefix_length, 32);
+
+  addrs_.resize(1ull << (32 - prefix_length), false);
+
+  // Mark the base address and broadcast address as allocated.
+  addrs_.front() = true;
+  addrs_.back() = true;
+}
+
+Subnet::~Subnet() {
+  release_cb_.Run();
+}
+
+std::unique_ptr<SubnetAddress> Subnet::Allocate(uint32_t addr) {
+  return AllocateAtOffset(OffsetFromBaseAddress(base_addr_, addr) - 1);
+}
+
+std::unique_ptr<SubnetAddress> Subnet::AllocateAtOffset(uint32_t offset) {
+  uint32_t addr = AddressAtOffset(offset);
+  if (addr == INADDR_ANY) {
+    return nullptr;
+  }
+
+  if (addrs_[offset + 1]) {
+    // Address is already allocated.
+    return nullptr;
+  }
+
+  addrs_[offset + 1] = true;
+  return std::make_unique<SubnetAddress>(
+      addr, prefix_length_,
+      base::Bind(&Subnet::Free, weak_factory_.GetWeakPtr(), offset + 1));
+}
+
+uint32_t Subnet::AddressAtOffset(uint32_t offset) const {
+  if (offset < 0 || offset >= AvailableCount())
+    return INADDR_ANY;
+
+  // The first usable IP is after the base address.
+  return AddOffset(base_addr_, 1 + offset);
+}
+
+uint32_t Subnet::AvailableCount() const {
+  // The available IP count is all IPs in a subnet, minus the network ID
+  // and the broadcast address.
+  return addrs_.size() - 2;
+}
+
+uint32_t Subnet::BaseAddress() const {
+  return base_addr_;
+}
+
+uint32_t Subnet::Netmask() const {
+  return Ipv4Netmask(prefix_length_);
+}
+
+uint32_t Subnet::Prefix() const {
+  return base_addr_ & Netmask();
+}
+
+uint32_t Subnet::PrefixLength() const {
+  return prefix_length_;
+}
+
+std::string Subnet::ToCidrString() const {
+  return IPv4AddressToCidrString(base_addr_, prefix_length_);
+}
+
+void Subnet::Free(uint32_t offset) {
+  DCHECK_NE(offset, 0);
+  DCHECK_LT(offset, addrs_.size() - 1);
+
+  addrs_[offset] = false;
+}
+
+}  // namespace patchpanel