proxygen
MacAddress.h
Go to the documentation of this file.
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <iosfwd>
20 
21 #include <folly/Range.h>
22 #include <folly/lang/Bits.h>
23 
24 namespace folly {
25 
26 class IPAddressV6;
27 
28 /*
29  * MacAddress represents an IEEE 802 MAC address.
30  */
31 class MacAddress {
32  public:
33  static constexpr size_t SIZE = 6;
34  static const MacAddress BROADCAST;
35  static const MacAddress ZERO;
36 
37  /*
38  * Construct a zero-initialized MacAddress.
39  */
41  memset(&bytes_, 0, 8);
42  }
43 
44  /*
45  * Parse a MacAddress from a human-readable string.
46  * The string must contain 6 one- or two-digit hexadecimal
47  * numbers, separated by dashes or colons.
48  * Examples: 00:02:C9:C8:F9:68 or 0-2-c9-c8-f9-68
49  */
50  explicit MacAddress(StringPiece str);
51 
52  /*
53  * Construct a MAC address from its 6-byte binary value
54  */
56  MacAddress ret;
57  ret.setFromBinary(value);
58  return ret;
59  }
60 
61  /*
62  * Construct a MacAddress from a uint64_t in network byte order.
63  *
64  * The first two bytes are ignored, and the MAC address is taken from the
65  * latter 6 bytes.
66  *
67  * This is a static method rather than a constructor to avoid confusion
68  * between host and network byte order constructors.
69  */
71  return MacAddress(value);
72  }
73 
74  /*
75  * Construct a MacAddress from a uint64_t in host byte order.
76  *
77  * The most significant two bytes are ignored, and the MAC address is taken
78  * from the least significant 6 bytes.
79  *
80  * This is a static method rather than a constructor to avoid confusion
81  * between host and network byte order constructors.
82  */
84  return MacAddress(Endian::big(value));
85  }
86 
87  /*
88  * Construct the multicast MacAddress for the specified multicast IPv6
89  * address.
90  */
92 
93  /*
94  * Get a pointer to the MAC address' binary value.
95  *
96  * The returned value points to internal storage inside the MacAddress
97  * object. It is only valid as long as the MacAddress, and its contents may
98  * change if the MacAddress is updated.
99  */
100  const uint8_t* bytes() const {
101  return bytes_ + 2;
102  }
103 
104  /*
105  * Return the address as a uint64_t, in network byte order.
106  *
107  * The first two bytes will be 0, and the subsequent 6 bytes will contain
108  * the address in network byte order.
109  */
110  uint64_t u64NBO() const {
111  return packedBytes();
112  }
113 
114  /*
115  * Return the address as a uint64_t, in host byte order.
116  *
117  * The two most significant bytes will be 0, and the remaining 6 bytes will
118  * contain the address. The most significant of these 6 bytes will contain
119  * the first byte that appear on the wire, and the least significant byte
120  * will contain the last byte.
121  */
122  uint64_t u64HBO() const {
123  // Endian::big() does what we want here, even though we are converting
124  // from big-endian to host byte order. This swaps if and only if
125  // the host byte order is little endian.
126  return Endian::big(packedBytes());
127  }
128 
129  /*
130  * Return a human-readable representation of the MAC address.
131  */
132  std::string toString() const;
133 
134  /*
135  * Update the current MacAddress object from a human-readable string.
136  */
137  void parse(StringPiece str);
138 
139  /*
140  * Update the current MacAddress object from a 6-byte binary representation.
141  */
143 
144  bool isBroadcast() const {
145  return *this == BROADCAST;
146  }
147  bool isMulticast() const {
148  return getByte(0) & 0x1;
149  }
150  bool isUnicast() const {
151  return !isMulticast();
152  }
153 
154  /*
155  * Return true if this MAC address is locally administered.
156  *
157  * Locally administered addresses are assigned by the local network
158  * administrator, and are not guaranteed to be globally unique. (It is
159  * similar to IPv4's private address space.)
160  *
161  * Note that isLocallyAdministered() will return true for the broadcast
162  * address, since it has the locally administered bit set.
163  */
164  bool isLocallyAdministered() const {
165  return getByte(0) & 0x2;
166  }
167 
168  // Comparison operators.
169 
170  bool operator==(const MacAddress& other) const {
171  // All constructors and modifying methods make sure padding is 0,
172  // so we don't need to mask these bytes out when comparing here.
173  return packedBytes() == other.packedBytes();
174  }
175 
176  bool operator<(const MacAddress& other) const {
177  return u64HBO() < other.u64HBO();
178  }
179 
180  bool operator!=(const MacAddress& other) const {
181  return !(*this == other);
182  }
183 
184  bool operator>(const MacAddress& other) const {
185  return other < *this;
186  }
187 
188  bool operator>=(const MacAddress& other) const {
189  return !(*this < other);
190  }
191 
192  bool operator<=(const MacAddress& other) const {
193  return !(*this > other);
194  }
195 
196  private:
197  explicit MacAddress(uint64_t valueNBO) {
198  memcpy(&bytes_, &valueNBO, 8);
199  // Set the pad bytes to 0.
200  // This allows us to easily compare two MacAddresses,
201  // without having to worry about differences in the padding.
202  bytes_[0] = 0;
203  bytes_[1] = 0;
204  }
205 
206  /* We store the 6 bytes starting at bytes_[2] (most significant)
207  through bytes_[7] (least).
208  bytes_[0] and bytes_[1] are always equal to 0 to simplify comparisons.
209  */
210  unsigned char bytes_[8];
211 
212  inline uint64_t getByte(size_t index) const {
213  return bytes_[index + 2];
214  }
215 
217  uint64_t u64;
218  memcpy(&u64, bytes_, 8);
219  return u64;
220  }
221 };
222 
223 /* Define toAppend() so to<string> will work */
224 template <class Tgt>
226  MacAddress address,
227  Tgt* result) {
228  toAppend(address.toString(), result);
229 }
230 
231 std::ostream& operator<<(std::ostream& os, MacAddress address);
232 
233 } // namespace folly
234 
235 namespace std {
236 
237 // Provide an implementation for std::hash<MacAddress>
238 template <>
239 struct hash<folly::MacAddress> {
240  size_t operator()(const folly::MacAddress& address) const {
241  return std::hash<uint64_t>()(address.u64HBO());
242  }
243 };
244 
245 } // namespace std
std::string toString() const
Definition: MacAddress.cpp:50
PskType type
bool operator<(const MacAddress &other) const
Definition: MacAddress.h:176
uint64_t u64NBO() const
Definition: MacAddress.h:110
STL namespace.
static constexpr size_t SIZE
Definition: MacAddress.h:33
MacAddress(uint64_t valueNBO)
Definition: MacAddress.h:197
size_t operator()(const folly::MacAddress &address) const
Definition: MacAddress.h:240
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
static MacAddress createMulticast(IPAddressV6 addr)
Definition: MacAddress.cpp:39
bool operator>=(const MacAddress &other) const
Definition: MacAddress.h:188
static const MacAddress ZERO
Definition: MacAddress.h:35
bool isLocallyAdministered() const
Definition: MacAddress.h:164
static MacAddress fromHBO(uint64_t value)
Definition: MacAddress.h:83
void parse(StringPiece str)
Definition: MacAddress.cpp:74
uint64_t packedBytes() const
Definition: MacAddress.h:216
bool operator!=(const MacAddress &other) const
Definition: MacAddress.h:180
bool operator==(const MacAddress &other) const
Definition: MacAddress.h:170
const uint8_t * bytes() const
Definition: MacAddress.h:100
bool isMulticast() const
Definition: MacAddress.h:147
static T big(T x)
Definition: Bits.h:259
bool operator<=(const MacAddress &other) const
Definition: MacAddress.h:192
static const char *const value
Definition: Conv.cpp:50
void toAppend(char value, Tgt *result)
Definition: Conv.h:406
static const MacAddress BROADCAST
Definition: MacAddress.h:34
static MacAddress fromBinary(ByteRange value)
Definition: MacAddress.h:55
void setFromBinary(ByteRange value)
Definition: MacAddress.cpp:139
static MacAddress fromNBO(uint64_t value)
Definition: MacAddress.h:70
uint64_t u64HBO() const
Definition: MacAddress.h:122
const char * string
Definition: Conv.cpp:212
bool isBroadcast() const
Definition: MacAddress.h:144
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
bool isUnicast() const
Definition: MacAddress.h:150
unsigned char bytes_[8]
Definition: MacAddress.h:210
bool operator>(const MacAddress &other) const
Definition: MacAddress.h:184
ThreadPoolListHook * addr
uint64_t getByte(size_t index) const
Definition: MacAddress.h:212
std::ostream & operator<<(std::ostream &out, dynamic const &d)
Definition: dynamic-inl.h:1158