blob: 6a191d5ba86e00f7e19c580456e7328d0f8b5495 [file] [log] [blame]
// Copyright 2017 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 "arc/network/mac_address_generator.h"
#include <base/rand_util.h>
namespace arc_networkd {
namespace {
constexpr MacAddress kStableBaseAddr = {0x42, 0x37, 0x05, 0x13, 0x17, 0x00};
} // namespace
MacAddress MacAddressGenerator::Generate() {
MacAddress addr;
do {
base::RandBytes(addr.data(), addr.size());
// Set the locally administered flag.
addr[0] |= static_cast<uint8_t>(0x02);
// Unset the multicast flag.
addr[0] &= static_cast<uint8_t>(0xfe);
} while (addrs_.find(addr) != addrs_.end() ||
(addr[0] == kStableBaseAddr[0] && addr[1] == kStableBaseAddr[1] &&
addr[2] == kStableBaseAddr[2] && addr[3] == kStableBaseAddr[3] &&
addr[4] == kStableBaseAddr[4]));
addrs_.insert(addr);
return addr;
}
MacAddress MacAddressGenerator::GetStable(uint8_t id) const {
MacAddress addr = kStableBaseAddr;
addr[5] = id;
return addr;
}
bool MacAddressGenerator::Insert(const MacAddress& addr) {
// Validate the address.
if ((addr[0] & 0x02U) == 0) {
// Locally administered bit is not set.
return false;
}
if ((addr[0] & 0x01U) != 0) {
// Multicast bit is set.
return false;
}
addrs_.insert(addr);
return true;
}
} // namespace arc_networkd