Apache Mesos
mac.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_MAC_HPP__
14 #define __STOUT_MAC_HPP__
15 
16 #include <stdint.h>
17 #include <stdio.h>
18 #include <string.h>
19 
20 #ifndef __WINDOWS__
21 #include <arpa/inet.h>
22 #endif // __WINDOWS__
23 
24 #ifdef __linux__
25 #include <linux/if.h>
26 #include <linux/if_packet.h>
27 #endif
28 
29 #ifndef __WINDOWS__
30 #include <net/ethernet.h>
31 #endif // __WINDOWS__
32 
33 #ifdef __APPLE__
34 #include <net/if.h>
35 #include <net/if_dl.h>
36 #include <net/if_types.h>
37 #endif
38 
39 #ifndef __WINDOWS__
40 #include <sys/socket.h>
41 #endif // __WINDOWS__
42 #include <sys/types.h>
43 
44 #include <iostream>
45 #include <string>
46 
47 #include <stout/abort.hpp>
48 #include <stout/error.hpp>
49 #include <stout/none.hpp>
50 #include <stout/result.hpp>
51 #include <stout/stringify.hpp>
52 #include <stout/strings.hpp>
53 #include <stout/try.hpp>
54 
55 
56 // Network utilities.
57 namespace net {
58 
59 // Represents a MAC address. A MAC address is a 48-bit unique
60 // identifier assigned to a network interface for communications on
61 // the physical network segment. We use a byte array (in transmission
62 // order) to represent a MAC address. For example, for a MAC address
63 // 01:23:34:67:89:ab, the format is shown as follows:
64 //
65 // MSB LSB
66 // | |
67 // v v
68 // +--------+--------+--------+--------+--------+--------+
69 // |bytes[0]|bytes[1]|bytes[2]|bytes[3]|bytes[4]|bytes[5]|
70 // +--------+--------+--------+--------+--------+--------+
71 //
72 // 01 : 23 : 45 : 67 : 89 : ab
73 // NOLINT(readability/ending_punctuation)
74 class MAC
75 {
76 public:
77  // Parse a MAC address (e.g., 01:23:34:67:89:ab).
78  static Try<MAC> parse(const std::string& s)
79  {
80  std::vector<std::string> tokens = strings::split(s, ":");
81  if (tokens.size() != 6) {
82  return Error("Invalid format. Expecting xx:xx:xx:xx:xx:xx");
83  }
84 
85  auto isValidHexDigit = [](char c) {
86  return (c >= '0' && c <= '9') ||
87  (c >= 'a' && c <= 'f') ||
88  (c >= 'A' && c <= 'F');
89  };
90 
91  uint8_t bytes[6];
92  for (size_t i = 0; i < 6; i++) {
93  if (tokens[i].size() != 2) {
94  return Error("Not a two digit hex number");
95  }
96 
97  if (!isValidHexDigit(tokens[i][0]) ||
98  !isValidHexDigit(tokens[i][1])) {
99  return Error("Not a valid hex number");
100  }
101 
102  const char* str = tokens[i].c_str();
103  char *endptr = nullptr;
104  unsigned long value = strtoul(str, &endptr, 16);
105 
106  assert(endptr == str + 2);
107  assert(value < 256);
108 
109  bytes[i] = static_cast<uint8_t>(value);
110  }
111 
112  return MAC(bytes);
113  }
114 
115  // Constructs a MAC address from a byte array.
116  explicit MAC(const uint8_t (&_bytes)[6])
117  {
118  for (size_t i = 0; i < 6; i++) {
119  bytes[i] = _bytes[i];
120  }
121  }
122 
123  // Returns the byte at the given index. For example, for a MAC
124  // address 01:23:45:67:89:ab, mac[0] = 01, mac[1] = 23 and etc.
125  uint8_t operator[](size_t index) const
126  {
127  if (index >= 6) {
128  ABORT("Invalid index specified in MAC::operator[]\n");
129  }
130 
131  return bytes[index];
132  }
133 
134  bool operator==(const MAC& that) const
135  {
136  for (size_t i = 0; i < 6; i++) {
137  if (bytes[i] != that.bytes[i]) {
138  return false;
139  }
140  }
141  return true;
142  }
143 
144  bool operator!=(const MAC& that) const
145  {
146  return !(*this == that);
147  }
148 
149 private:
150  // Byte array of this MAC address (in transmission order).
151  uint8_t bytes[6];
152 };
153 
154 
155 // Returns the standard string format (IEEE 802) of the given MAC
156 // address, which contains six groups of two hexadecimal digits,
157 // separated by colons, in transmission order (e.g.,
158 // 01:23:45:67:89:ab).
159 inline std::ostream& operator<<(std::ostream& stream, const MAC& mac)
160 {
161  char buffer[18];
162 
163  sprintf(
164  buffer,
165  "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
166  mac[0],
167  mac[1],
168  mac[2],
169  mac[3],
170  mac[4],
171  mac[5]);
172 
173  return stream << buffer;
174 }
175 
176 } // namespace net {
177 
178 
179 // NOTE: These headers are placed here because the platform specific code
180 // requires classes defined in this file.
181 #ifdef __WINDOWS__
182 #include <stout/windows/mac.hpp>
183 #else
184 #include <stout/posix/mac.hpp>
185 #endif // __WINDOWS__
186 
187 #endif // __STOUT_MAC_HPP__
Definition: errorbase.hpp:36
#define ABORT(...)
Definition: abort.hpp:40
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:130
std::ostream & operator<<(std::ostream &stream, const IP &ip)
Definition: ip.hpp:503
Definition: check.hpp:33
uint8_t operator[](size_t index) const
Definition: mac.hpp:125
MAC(const uint8_t(&_bytes)[6])
Definition: mac.hpp:116
static Try< MAC > parse(const std::string &s)
Definition: mac.hpp:78
Definition: ip.hpp:70
Definition: mac.hpp:74
Result< MAC > mac(const std::string &name)
Definition: mac.hpp:33
std::vector< std::string > split(const std::string &s, const std::string &delims, const Option< size_t > &maxTokens=None())
Definition: strings.hpp:184
bool operator==(const MAC &that) const
Definition: mac.hpp:134
bool operator!=(const MAC &that) const
Definition: mac.hpp:144