vn-verdnaturachat/ios/Pods/Folly/folly/MacAddress.h

246 lines
6.5 KiB
C++

/*
* Copyright 2014-present Facebook, Inc.
*
* 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.
*/
#pragma once
#include <iosfwd>
#include <folly/Range.h>
#include <folly/lang/Bits.h>
namespace folly {
class IPAddressV6;
/*
* MacAddress represents an IEEE 802 MAC address.
*/
class MacAddress {
public:
static constexpr size_t SIZE = 6;
static const MacAddress BROADCAST;
static const MacAddress ZERO;
/*
* Construct a zero-initialized MacAddress.
*/
MacAddress() {
memset(&bytes_, 0, 8);
}
/*
* Parse a MacAddress from a human-readable string.
* The string must contain 6 one- or two-digit hexadecimal
* numbers, separated by dashes or colons.
* Examples: 00:02:C9:C8:F9:68 or 0-2-c9-c8-f9-68
*/
explicit MacAddress(StringPiece str);
/*
* Construct a MAC address from its 6-byte binary value
*/
static MacAddress fromBinary(ByteRange value) {
MacAddress ret;
ret.setFromBinary(value);
return ret;
}
/*
* Construct a MacAddress from a uint64_t in network byte order.
*
* The first two bytes are ignored, and the MAC address is taken from the
* latter 6 bytes.
*
* This is a static method rather than a constructor to avoid confusion
* between host and network byte order constructors.
*/
static MacAddress fromNBO(uint64_t value) {
return MacAddress(value);
}
/*
* Construct a MacAddress from a uint64_t in host byte order.
*
* The most significant two bytes are ignored, and the MAC address is taken
* from the least significant 6 bytes.
*
* This is a static method rather than a constructor to avoid confusion
* between host and network byte order constructors.
*/
static MacAddress fromHBO(uint64_t value) {
return MacAddress(Endian::big(value));
}
/*
* Construct the multicast MacAddress for the specified multicast IPv6
* address.
*/
static MacAddress createMulticast(IPAddressV6 addr);
/*
* Get a pointer to the MAC address' binary value.
*
* The returned value points to internal storage inside the MacAddress
* object. It is only valid as long as the MacAddress, and its contents may
* change if the MacAddress is updated.
*/
const uint8_t* bytes() const {
return bytes_ + 2;
}
/*
* Return the address as a uint64_t, in network byte order.
*
* The first two bytes will be 0, and the subsequent 6 bytes will contain
* the address in network byte order.
*/
uint64_t u64NBO() const {
return packedBytes();
}
/*
* Return the address as a uint64_t, in host byte order.
*
* The two most significant bytes will be 0, and the remaining 6 bytes will
* contain the address. The most significant of these 6 bytes will contain
* the first byte that appear on the wire, and the least significant byte
* will contain the last byte.
*/
uint64_t u64HBO() const {
// Endian::big() does what we want here, even though we are converting
// from big-endian to host byte order. This swaps if and only if
// the host byte order is little endian.
return Endian::big(packedBytes());
}
/*
* Return a human-readable representation of the MAC address.
*/
std::string toString() const;
/*
* Update the current MacAddress object from a human-readable string.
*/
void parse(StringPiece str);
/*
* Update the current MacAddress object from a 6-byte binary representation.
*/
void setFromBinary(ByteRange value);
bool isBroadcast() const {
return *this == BROADCAST;
}
bool isMulticast() const {
return getByte(0) & 0x1;
}
bool isUnicast() const {
return !isMulticast();
}
/*
* Return true if this MAC address is locally administered.
*
* Locally administered addresses are assigned by the local network
* administrator, and are not guaranteed to be globally unique. (It is
* similar to IPv4's private address space.)
*
* Note that isLocallyAdministered() will return true for the broadcast
* address, since it has the locally administered bit set.
*/
bool isLocallyAdministered() const {
return getByte(0) & 0x2;
}
// Comparison operators.
bool operator==(const MacAddress& other) const {
// All constructors and modifying methods make sure padding is 0,
// so we don't need to mask these bytes out when comparing here.
return packedBytes() == other.packedBytes();
}
bool operator<(const MacAddress& other) const {
return u64HBO() < other.u64HBO();
}
bool operator!=(const MacAddress& other) const {
return !(*this == other);
}
bool operator>(const MacAddress& other) const {
return other < *this;
}
bool operator>=(const MacAddress& other) const {
return !(*this < other);
}
bool operator<=(const MacAddress& other) const {
return !(*this > other);
}
private:
explicit MacAddress(uint64_t valueNBO) {
memcpy(&bytes_, &valueNBO, 8);
// Set the pad bytes to 0.
// This allows us to easily compare two MacAddresses,
// without having to worry about differences in the padding.
bytes_[0] = 0;
bytes_[1] = 0;
}
/* We store the 6 bytes starting at bytes_[2] (most significant)
through bytes_[7] (least).
bytes_[0] and bytes_[1] are always equal to 0 to simplify comparisons.
*/
unsigned char bytes_[8];
inline uint64_t getByte(size_t index) const {
return bytes_[index + 2];
}
uint64_t packedBytes() const {
uint64_t u64;
memcpy(&u64, bytes_, 8);
return u64;
}
};
/* Define toAppend() so to<string> will work */
template <class Tgt>
typename std::enable_if<IsSomeString<Tgt>::value>::type toAppend(
MacAddress address,
Tgt* result) {
toAppend(address.toString(), result);
}
std::ostream& operator<<(std::ostream& os, MacAddress address);
} // namespace folly
namespace std {
// Provide an implementation for std::hash<MacAddress>
template <>
struct hash<folly::MacAddress> {
size_t operator()(const folly::MacAddress& address) const {
return std::hash<uint64_t>()(address.u64HBO());
}
};
} // namespace std