#ifndef MACADDRESS_H #define MACADDRESS_H #include #include #include "../Exception.h" /** * describes a MAC-Address as 64-bit integer. * provides 8-bit access to all 6 values */ union MACAddress { private: /** fieldwise access */ struct { uint8_t h5; uint8_t h4; uint8_t h3; uint8_t h2; uint8_t h1; uint8_t h0; } fields; /** store as 64-bit integer */ uint64_t mac; public: /** empty ctor */ MACAddress() { ; } /** copy ctor */ MACAddress(const MACAddress& o) : mac(o.mac) { ; } /** ctor form long */ MACAddress(const uint64_t mac) : mac(mac) { ; } /** ctor form string (e.g. "xx:xx:xx:xx:xx:xx") */ MACAddress(const std::string& str) { // sanity check if (str.size() != 17) {throw Exception("invalid hex string length. must be 17");} mac = 0; // all zeros fields.h5 = hexWordToInt(str[ 0], str[ 1]); fields.h4 = hexWordToInt(str[ 3], str[ 4]); fields.h3 = hexWordToInt(str[ 6], str[ 7]); fields.h2 = hexWordToInt(str[ 9], str[10]); fields.h1 = hexWordToInt(str[12], str[13]); fields.h0 = hexWordToInt(str[15], str[16]); } /** convert to hex-string ("xx:xx:xx:xx:xx:xx") */ std::string asString() const { std::string str = ":::::::::::::::::"; intToHexStr(fields.h5, &str[ 0]); intToHexStr(fields.h4, &str[ 3]); intToHexStr(fields.h3, &str[ 6]); intToHexStr(fields.h2, &str[ 9]); intToHexStr(fields.h1, &str[12]); intToHexStr(fields.h0, &str[15]); return str; } /** get the mac address as a long-int value */ uint64_t asLong() const { return mac; } /** equal? */ bool operator == (const MACAddress& o) const { return o.asLong() == asLong(); } private: /** convert the given hex char [0-F] to an integer [0-15] */ static uint8_t hexCharToInt(const char _hex) { // to upper case const char hex = (_hex >= 'a') ? (_hex - ('a' - 'A')) : (_hex); // convert return (hex - '0' < 10) ? (hex - '0') : (hex - 'A' + 10); } /** convert the given hex-word to an integer */ static uint8_t hexWordToInt(const char hi, const char lo) { return hexCharToInt(hi) << 4 | hexCharToInt(lo); } /** conver the given integer [0-15] to a hex char [0-F] */ static char intToHexChar(const uint8_t val) { return (val < 10) ? ('0' + val) : ('A' - 10 + val); } /** insert two hex chars into the provided string buffer */ static void intToHexStr(const uint8_t val, char* dst) { dst[0] = intToHexChar((val >> 4) & 0xF); dst[1] = intToHexChar((val >> 0) & 0xF); } }; /** hash-method for MAC-Addresses */ namespace std { template <> struct hash { std::size_t operator() (const MACAddress& mac) const { return std::hash()(mac.asLong()); } }; } #endif // MACADDRESS_H