-
Notifications
You must be signed in to change notification settings - Fork 267
/
macaddress.cpp
125 lines (104 loc) · 3.41 KB
/
macaddress.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#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;
}