libtins 4.5
Loading...
Searching...
No Matches
hw_address.h
1/*
2 * Copyright (c) 2017, Matias Fontanini
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef TINS_HWADDRESS_H
31#define TINS_HWADDRESS_H
32
33#include <stdint.h>
34#include <iosfwd>
35#include <string>
36#include <cstring>
37#include <tins/cxxstd.h>
38#include <tins/macros.h>
39#if TINS_IS_CXX11
40 // std::hash
41 #include <memory>
42#endif // TINS_IS_CXX11
43
44namespace Tins {
45namespace Internals {
46
47// Defined in hw_address.cpp
51TINS_API std::string hw_address_to_string(const uint8_t* ptr, size_t count);
52
53TINS_API void string_to_hw_address(const std::string& hw_addr, uint8_t* output,
54 size_t output_size);
55
56TINS_API bool hw_address_equal_compare(const uint8_t* start1, const uint8_t* end1,
57 const uint8_t* start2);
58
59TINS_API bool hw_address_lt_compare(const uint8_t* start1, const uint8_t* end1,
60 const uint8_t* start2, const uint8_t* end2);
61
62TINS_API bool hw_address_gt_compare(const uint8_t* start1, const uint8_t* end1,
63 const uint8_t* start2, const uint8_t* end2);
64
68} // Internals
69
90template<size_t n>
91class HWAddress {
92public:
96 typedef uint8_t storage_type;
97
102
107
112 static const size_t address_size = n;
113
118
134 HWAddress(const storage_type* ptr = 0) {
135 if (ptr) {
136 std::memcpy(buffer_, ptr, address_size);
137 }
138 else {
139 std::memset(buffer_, 0, address_size);
140 }
141 }
142
154 HWAddress(const std::string& address) {
155 Internals::string_to_hw_address(address, buffer_, n);
156 }
157
171 template<size_t i>
172 HWAddress(const char (&address)[i]) {
173 Internals::string_to_hw_address(address, buffer_, n);
174 }
175
188 template<size_t i>
190 size_t copy_threshold = i < n ? i : n;
191 for (size_t index = 0; index < n; ++index) {
192 if (index < copy_threshold) {
193 buffer_[index] = rhs[index];
194 }
195 else {
196 buffer_[index] = storage_type();
197 }
198 }
199 }
200
208 return buffer_;
209 }
210
218 return buffer_;
219 }
220
228 return buffer_ + address_size;
229 }
230
238 return buffer_ + address_size;
239 }
240
248 bool operator==(const HWAddress& rhs) const {
249 return Internals::hw_address_equal_compare(begin(), end(), rhs.begin());
250 }
251
259 bool operator!=(const HWAddress& rhs) const {
260 return !(*this == rhs);
261 }
262
270 bool operator<(const HWAddress& rhs) const {
271 return Internals::hw_address_lt_compare(begin(), end(), rhs.begin(), rhs.end());
272 }
273
281 bool operator<=(const HWAddress& rhs) const {
282 return !operator>(rhs);
283 }
284
292 bool operator>(const HWAddress& rhs) const {
293 return Internals::hw_address_gt_compare(begin(), end(), rhs.begin(), rhs.end());
294 }
295
303 bool operator>=(const HWAddress& rhs) const {
304 return !operator<(rhs);
305 }
306
313 HWAddress operator&(const HWAddress& mask) const {
314 HWAddress<n> output = *this;
315 for (size_t i = 0; i < n; ++i) {
316 output[i] = output[i] & mask[i];
317 }
318 return output;
319 }
320
327 HWAddress operator|(const HWAddress& mask) const {
328 HWAddress<n> output = *this;
329 for (size_t i = 0; i < n; ++i) {
330 output[i] = output[i] | mask[i];
331 }
332 return output;
333 }
334
340 HWAddress<n> output = *this;
341 for (size_t i = 0; i < n; ++i) {
342 output[i] = ~output[i];
343 }
344 return output;
345 }
346
352 size_t size() const {
353 return address_size;
354 }
355
359 bool is_broadcast() const {
360 return* this == broadcast;
361 }
362
366 bool is_multicast() const {
367 return (*begin() & 0x01);
368 }
369
373 bool is_unicast() const {
374 return !is_broadcast() && !is_multicast();
375 }
376
382 std::string to_string() const {
383 return Internals::hw_address_to_string(buffer_, size());
384 }
385
391 storage_type operator[](size_t i) const {
392 return begin()[i];
393 }
394
401 return begin()[i];
402 }
403
411 friend std::ostream& operator<<(std::ostream& os, const HWAddress& addr) {
412 return os << addr.to_string();
413 }
414
430 template<typename OutputIterator>
431 OutputIterator copy(OutputIterator output) const {
432 for (const_iterator iter = begin(); iter != end(); ++iter) {
433 *output++ = *iter;
434 }
435 return output;
436 }
437private:
438 static HWAddress<n> make_broadcast_address() {
439 // Build a buffer made of n 0xff bytes
440 uint8_t buffer[n];
441 for (size_t i = 0; i < n; ++i) {
442 buffer[i] = 0xff;
443 }
444 return HWAddress<n>(buffer);
445 }
446
447 storage_type buffer_[n];
448};
449
450template<size_t n>
451const HWAddress<n> HWAddress<n>::broadcast = make_broadcast_address();
452
453} // namespace Tins
454
455#if TINS_IS_CXX11
456namespace std {
457
458// Specialization of std::hash for HWAddress
459template<size_t n>
460struct hash<Tins::HWAddress<n>> {
461 size_t operator()(const Tins::HWAddress<n>& addr) const {
462 return std::hash<std::string>()(addr.to_string());
463 }
464};
465
466} // namespace std
467#endif // TINS_IS_CXX11
468
469#endif // TINS_HWADDRESS_H
Represents a hardware address.
Definition resolve_utils.h:43
const_iterator end() const
Retrieves a const iterator pointing one-past-the-end of the address.
Definition hw_address.h:237
iterator end()
Retrieves an iterator pointing one-past-the-end of the address.
Definition hw_address.h:227
bool is_multicast() const
Indicates whether this is a multicast address.
Definition hw_address.h:366
const storage_type * const_iterator
Const iterator type.
Definition hw_address.h:106
OutputIterator copy(OutputIterator output) const
Helper function which copies the address into an output iterator.
Definition hw_address.h:431
bool operator>(const HWAddress &rhs) const
Compares this HWAddress for greater-than inequality.
Definition hw_address.h:292
static const size_t address_size
Non-member constant indicating the amount of storage_type elements in this address.
Definition hw_address.h:112
bool operator>=(const HWAddress &rhs) const
Compares this HWAddress for greater-than equality.
Definition hw_address.h:303
bool operator==(const HWAddress &rhs) const
Compares this HWAddress for equality.
Definition hw_address.h:248
const_iterator begin() const
Retrieves a const iterator pointing to the begining of the address.
Definition hw_address.h:217
bool operator<=(const HWAddress &rhs) const
Compares this HWAddress for less-than equality.
Definition hw_address.h:281
friend std::ostream & operator<<(std::ostream &os, const HWAddress &addr)
Writes this HWAddress in hex-notation to a std::ostream.
Definition hw_address.h:411
HWAddress operator|(const HWAddress &mask) const
Apply a mask to this address.
Definition hw_address.h:327
bool is_broadcast() const
Indicates whether this is a broadcast address.
Definition hw_address.h:359
bool is_unicast() const
Indicates whether this is an unicast address.
Definition hw_address.h:373
bool operator!=(const HWAddress &rhs) const
Compares this HWAddress for in-equality.
Definition hw_address.h:259
uint8_t storage_type
The type of the elements stored in the hardware address.
Definition hw_address.h:96
size_t size() const
Retrieves the size of this address.
Definition hw_address.h:352
HWAddress operator~() const
not operator
Definition hw_address.h:339
HWAddress operator&(const HWAddress &mask) const
Apply a mask to this address.
Definition hw_address.h:313
storage_type * iterator
The random access iterator type.
Definition hw_address.h:101
std::string to_string() const
Convert this address to a hex-notation std::string address.
Definition hw_address.h:382
bool operator<(const HWAddress &rhs) const
Compares this HWAddress for less-than inequality.
Definition hw_address.h:270
HWAddress(const HWAddress< i > &rhs)
Copy construct from a HWAddress of length i.
Definition hw_address.h:189
storage_type operator[](size_t i) const
Retrieves the i-th storage_type in this address.
Definition hw_address.h:391
iterator begin()
Retrieves an iterator pointing to the begining of the address.
Definition hw_address.h:207
storage_type & operator[](size_t i)
Retrieves the i-th storage_type in this address.
Definition hw_address.h:400
HWAddress(const char(&address)[i])
Overload provided basically for string literals.
Definition hw_address.h:172
HWAddress(const storage_type *ptr=0)
Constructor from a const storage_type*.
Definition hw_address.h:134
static const HWAddress< n > broadcast
The broadcast address.
Definition hw_address.h:117
HWAddress(const std::string &address)
Constructs an address from a hex-notation address.
Definition hw_address.h:154
The Tins namespace.
Definition address_range.h:38