MACAddress.cci
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 /** \file
15  \brief MACAddress inline non-template implementation */
16 
17 // Custom includes
18 //#include <algorithm>
19 #include <endian.h>
20 #include <boost/functional/hash.hpp>
21 #include "EUI64.hh"
22 
23 #define prefix_ inline
24 //-/////////////////////////////////////////////////////////////////////////////////////////////////
25 
26 //-/////////////////////////////////////////////////////////////////////////////////////////////////
27 // senf::MACAddress
28 
29 prefix_ senf::MACAddress::MACAddress()
30 {
31  fill(0u);
32 }
33 
34 prefix_ senf::MACAddress::MACAddress(senf::NoInit_t)
35 {}
36 
37 prefix_ senf::MACAddress::MACAddress(std::uint64_t const & v)
38 {
39  (*this)[0] = std::uint8_t( v >> 40 );
40  (*this)[1] = std::uint8_t( v >> 32 );
41  (*this)[2] = std::uint8_t( v >> 24 );
42  (*this)[3] = std::uint8_t( v >> 16 );
43  (*this)[4] = std::uint8_t( v >> 8 );
44  (*this)[5] = std::uint8_t( v );
45 }
46 
47 prefix_ void senf::MACAddress::local(bool flag)
48 {
49  if (flag) (*this)[0] |= 0x02;
50  else (*this)[0] &= ~0x02;
51 }
52 
53 prefix_ void senf::MACAddress::multicast(bool flag)
54 {
55  if (flag) (*this)[0] |= 0x01;
56  else (*this)[0] &= ~0x01;
57 }
58 
59 prefix_ bool senf::MACAddress::local()
60  const
61 {
62  return (*this)[0] & 0x02;
63 }
64 
65 prefix_ bool senf::MACAddress::multicast()
66  const
67 {
68  return (*this)[0] & 0x01;
69 }
70 
71 prefix_ bool senf::MACAddress::broadcast()
72  const
73 {
74  return (*reinterpret_cast<std::uint32_t const *>(&(*this)[0]) == 0xffffffff) and (*reinterpret_cast<std::uint16_t const *>(&(*this)[4]) == 0xffff);
75 }
76 
77 prefix_ senf::MACAddress::operator bool()
78  const
79 {
80  return (*reinterpret_cast<std::uint32_t const *>(&(*this)[0]) || *reinterpret_cast<std::uint16_t const *>(&(*this)[4]));
81 }
82 
83 prefix_ std::uint32_t senf::MACAddress::oui()
84  const
85 {
86  return
87  (std::uint32_t((*this)[0]) << 16) |
88  (std::uint32_t((*this)[1]) << 8) |
89  (*this)[2];
90 }
91 
92 prefix_ void senf::MACAddress::oui(std::uint32_t v)
93 {
94  (*this)[0] = (v >> 16) & 0xff;
95  (*this)[1] = (v >> 8) & 0xff;
96  (*this)[2] = (v >> 0) & 0xff;
97 }
98 
99 prefix_ std::uint32_t senf::MACAddress::nic()
100  const
101 {
102  return
103  (std::uint32_t((*this)[3]) << 16) |
104  (std::uint32_t((*this)[4]) << 8) |
105  (*this)[5];
106 }
107 
108 prefix_ void senf::MACAddress::nic(std::uint32_t v)
109 {
110  (*this)[3] = (v >> 16) & 0xff;
111  (*this)[4] = (v >> 8) & 0xff;
112  (*this)[5] = (v >> 0) & 0xff;
113 }
114 
115 prefix_ std::uint64_t senf::MACAddress::eui64()
116  const
117 {
118  return
119  (std::uint64_t( (*this)[0] ) << 56) |
120  (std::uint64_t( (*this)[1] ) << 48) |
121  (std::uint64_t( (*this)[2] ) << 40) |
122  (std::uint64_t( 0xfffe ) << 24) |
123  (std::uint64_t( (*this)[3] ) << 16) |
124  (std::uint64_t( (*this)[4] ) << 8) |
125  (std::uint64_t( (*this)[5] ) );
126 }
127 
128 prefix_ std::uint64_t senf::MACAddress::uint64()
129  const
130 {
131  std::uint64_t t;
132 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
133  std::reverse_copy(begin(), end(), (std::uint8_t*)&t);
134  *(((std::uint16_t*)&t)+3) = 0;
135 #else
136  std::copy(begin(), end(), ((std::uint8_t*)&t) + 2);
137  *(((std::uint16_t*)&t)) = 0;
138 #endif
139  return t;
140 }
141 
142 
143 prefix_ void senf::MACAddress::hash(std::uint64_t * hash, std::uint16_t const & otherKey)
144  const
145 {
146  std::copy(begin(), end(), (std::uint8_t*)hash);
147  *(((std::uint16_t*)hash) + 3) = otherKey;
148 }
149 
150 prefix_ std::uint32_t const & senf::MACAddress::hash32()
151  const
152 {
153  return *(reinterpret_cast<std::uint32_t const *> (&(*this)[2]));
154 }
155 
156 prefix_ bool senf::MACAddress::operator==(EUI64 const & eui64)
157  const
158 {
159  return eui64.isMACCompatible()
160  && std::equal(eui64.begin(), eui64.begin()+3, begin())
161  && std::equal(eui64.begin()+5, eui64.end(), begin()+3);
162 }
163 
164 prefix_ bool senf::operator==(EUI64 const & eui64, MACAddress const & mac)
165 {
166  return mac == eui64;
167 }
168 
169 prefix_ bool senf::MACAddress::operator<(MACAddress const & other)
170  const
171 {
172  return memcmp(&((*this)[0]), &other[0], 6) < 0;
173 }
174 
175 # if __SIZEOF_SIZE_T__ == 8
176 prefix_ std::size_t senf::hash_value(senf::MACAddress const & mac) noexcept
177 {
178  return boost::hash<std::uint64_t>().operator()(mac.uint64());
179 }
180 #elif __SIZEOF_SIZE_T__ == 4
181 prefix_ std::size_t const & senf::hash_value(senf::MACAddress const & mac) noexcept
182 {
183  return mac.hash32();
184 }
185 #else
186 prefix_ std::size_t senf::hash_value(senf::MACAddress const & mac) noexcept
187 {
188  BOOST_STATIC_ASSERT_MSG(true, "unknown sizeof(std::size_t)");
189 }
190 #endif
191 
192 
193 
194 //-/////////////////////////////////////////////////////////////////////////////////////////////////
195 #undef prefix_
196 
197 
198 // Local Variables:
199 // mode: c++
200 // fill-column: 100
201 // comment-column: 40
202 // c-file-style: "senf"
203 // indent-tabs-mode: nil
204 // ispell-local-dictionary: "american"
205 // compile-command: "scons -u test"
206 // End: