90d73d15c10dd9b6646cc4a2ed78a18e8714ecc8
[public/netxms.git] / src / libnetxms / macaddr.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Utility Library
4 ** Copyright (C) 2003-2017 Raden Solutions
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU Lesser General Public License as published
8 ** by the Free Software Foundation; either version 3 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU Lesser General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 ** File: macaddr.cpp
21 **
22 **/
23
24 #include "libnetxms.h"
25 #include <nxcpapi.h>
26 #include <netxms-regex.h>
27
28 /**
29 * Returns true if it is the multicast address
30 */
31 bool MacAddress::isMulticast() const
32 {
33 return (m_length == 6) ? (m_value[0] & 0x01) != 0 : false;
34 }
35
36 /**
37 * Returns true if it is the broadcast address
38 */
39 bool MacAddress::isBroadcast() const
40 {
41 return (m_length == 6) ? !memcmp(m_value, "\xFF\xFF\xFF\xFF\xFF\xFF", 6) : false;
42 }
43
44 /**
45 * Returns true if addrese are equals
46 */
47 bool MacAddress::equals(const MacAddress &a) const
48 {
49 if(a.length() == m_length)
50 {
51 return !memcmp(m_value, a.value(), m_length);
52 }
53 return false;
54 }
55
56 /**
57 * Returns string representaiton of mac address
58 */
59 TCHAR *MacAddress::toString(TCHAR *buffer, MacAddressNotation notation) const
60 {
61 switch(notation)
62 {
63 case MAC_ADDR_FLAT_STRING:
64 BinToStr(m_value, m_length, buffer);
65 break;
66 case MAC_ADDR_COLON_SEPARATED:
67 toStringInternal(buffer, _T(':'));
68 break;
69 case MAC_ADDR_BYTEPAIR_COLON_SEPARATED:
70 toStringInternal(buffer, _T(':'), true);
71 break;
72 case MAC_ADDR_HYPHEN_SEPARATED:
73 toStringInternal(buffer, _T('-'));
74 break;
75 case MAC_ADDR_DOT_SEPARATED:
76 toStringInternal(buffer, _T('.'));
77 break;
78 case MAC_ADDR_BYTEPAIR_DOT_SEPARATED:
79 toStringInternal(buffer, _T('.'), true);
80 break;
81 }
82 return buffer;
83 }
84
85 /**
86 * Internal method to string
87 */
88 TCHAR *MacAddress::toStringInternal(TCHAR *buffer, const TCHAR separator, bool bytePair) const
89 {
90 TCHAR *curr = buffer;
91
92 for(int i = 0; i < m_length; i++)
93 {
94 *curr++ = bin2hex(m_value[i] >> 4);
95 *curr++ = bin2hex(m_value[i] & 15);
96 if(!bytePair || (i % 2 == 0))
97 *curr++ = separator;
98 }
99 *(curr - 1) = 0;
100 return buffer;
101 }
102
103 /**
104 * Returns string representaiton of mac address
105 */
106 String MacAddress::toString(MacAddressNotation notation) const
107 {
108 if (m_length == 0)
109 return String();
110
111 int stringSize;
112 switch(notation)
113 {
114 case MAC_ADDR_FLAT_STRING:
115 stringSize = m_length * 2;
116 break;
117 case MAC_ADDR_COLON_SEPARATED:
118 case MAC_ADDR_HYPHEN_SEPARATED:
119 case MAC_ADDR_DOT_SEPARATED:
120 stringSize = m_length * 2 + m_length/2; //-1 separator +1 for
121 break;
122 case MAC_ADDR_BYTEPAIR_DOT_SEPARATED:
123 case MAC_ADDR_BYTEPAIR_COLON_SEPARATED:
124 stringSize = m_length * 2 + m_length/2; //-1 separator +1 for
125 break;
126 }
127 TCHAR *buf = (TCHAR *)malloc(stringSize * sizeof(TCHAR));
128 String str(toString(buf, notation));
129 free(buf);
130 return str;
131 }
132
133 /**
134 * Parse string as MAC address
135 */
136 MacAddress MacAddress::parse(const char *str)
137 {
138 if (str == NULL || strlen(str) > 23)
139 return MacAddress();
140
141 regex_t compRegex;
142 char exp[254] = { "^([0-9a-fA-F]{2})[ :-]?"
143 "([0-9a-fA-F]{2})[ :-]?"
144 "([0-9a-fA-F]{2})[ :-]?"
145 "([0-9a-fA-F]{2})[ :-]?"
146 "([0-9a-fA-F]{2})[ :-]?"
147 "([0-9a-fA-F]{2})[ :-]?"
148 "([0-9a-fA-F]{2})?[ :-]?"
149 "([0-9a-fA-F]{2})?$" };
150
151 String mac;
152 if (tre_regcomp(&compRegex, exp, REG_EXTENDED) == 0)
153 {
154 regmatch_t match[9];
155 if (tre_regexec(&compRegex, str, 9, match, 0) == 0)
156 {
157 for(int i = 1; i < 9; i++)
158 mac.appendMBString(str+match[i].rm_so, (match[i].rm_eo - match[i].rm_so), CP_ACP);
159 }
160 regfree(&compRegex);
161 }
162
163 if (mac.length() > 0)
164 {
165 BYTE buffer[16];
166 size_t size = StrToBin(mac, buffer, mac.length());
167 return MacAddress(buffer, size);
168 }
169
170 return MacAddress();
171 }
172
173 /**
174 * Parse string as MAC address (WCHAR version)
175 */
176 MacAddress MacAddress::parse(const WCHAR *str)
177 {
178 char mb[256];
179 WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, str, -1, mb, 256, NULL, NULL);
180 return parse(mb);
181 }