common/macaddress.cpp (98 lines of code) (raw):

#include <stdexcept> #include "macaddress.h" using namespace swss; using namespace std; const size_t mac_address_str_length = ETHER_ADDR_LEN*2 + 5; // 6 hexadecimal numbers (two digits each) + 5 delimiters MacAddress::MacAddress() { memset(m_mac, 0, ETHER_ADDR_LEN); } MacAddress::MacAddress(const uint8_t *mac) { memcpy(m_mac, mac, ETHER_ADDR_LEN); } MacAddress::MacAddress(const std::string& macStr) { bool suc = MacAddress::parseMacString(macStr, m_mac); if (!suc) throw invalid_argument("can't parse mac address '" + macStr + "'"); } const std::string MacAddress::to_string() const { return MacAddress::to_string(m_mac); } std::string MacAddress::to_string(const uint8_t* mac) { const static char char_table[] = "0123456789abcdef"; std::string str(mac_address_str_length, ':'); for(int i = 0; i < ETHER_ADDR_LEN; ++i) { int left = i * 3; // left digit position of hexadecimal number int right = left + 1; // right digit position of hexadecimal number int left_half = mac[i] >> 4; int right_half = mac[i] & 0x0f; str[left] = char_table[left_half]; str[right] = char_table[right_half]; } return str; } // This function parses a string to a binary mac address (uint8_t[6]) // The string should contain mac address only. No spaces are allowed. // The mac address separators could be either ':' or '-' bool MacAddress::parseMacString(const string& str_mac, uint8_t* bin_mac) { if (bin_mac == NULL) { return false; } if (str_mac.length() != mac_address_str_length) { return false; } const char* ptr_mac = str_mac.c_str(); // first check that all mac address separators are equal to each other // 2, 5, 8, 11, and 14 are MAC address separator positions if (!(ptr_mac[2] == ptr_mac[5] && ptr_mac[5] == ptr_mac[8] && ptr_mac[8] == ptr_mac[11] && ptr_mac[11] == ptr_mac[14])) { return false; } // then check that the first separator is equal to ':' or '-' if (ptr_mac[2] != ':' && ptr_mac[2] != '-') { return false; } for(int i = 0; i < ETHER_ADDR_LEN; ++i) { int left = i * 3; // left digit position of hexadecimal number int right = left + 1; // right digit position of hexadecimal number if (ptr_mac[left] >= '0' && ptr_mac[left] <= '9') { bin_mac[i] = static_cast<uint8_t>(ptr_mac[left] - '0'); } else if (ptr_mac[left] >= 'A' && ptr_mac[left] <= 'F') { bin_mac[i] = static_cast<uint8_t>(ptr_mac[left] - 'A' + 0x0a); } else if (ptr_mac[left] >= 'a' && ptr_mac[left] <= 'f') { bin_mac[i] = static_cast<uint8_t>(ptr_mac[left] - 'a' + 0x0a); } else { return false; } bin_mac[i] = static_cast<uint8_t>(bin_mac[i] << 4); if (ptr_mac[right] >= '0' && ptr_mac[right] <= '9') { bin_mac[i] |= static_cast<uint8_t>(ptr_mac[right] - '0'); } else if (ptr_mac[right] >= 'A' && ptr_mac[right] <= 'F') { bin_mac[i] |= static_cast<uint8_t>(ptr_mac[right] - 'A' + 0x0a); } else if (ptr_mac[right] >= 'a' && ptr_mac[right] <= 'f') { bin_mac[i] |= static_cast<uint8_t>(ptr_mac[right] - 'a' + 0x0a); } else { return false; } } return true; }