blob: 37193b828022b3a226876c6892f8ca3b52f0aee1 [file] [log] [blame]
Ratan Gupta594123d2017-05-16 22:48:35 +05301#include "util.hpp"
2
William A. Kennington III5058f572019-01-30 17:18:14 -08003#include <arpa/inet.h>
Gunnar Mills57d9c502018-09-14 14:42:34 -05004#include <netinet/in.h>
5
William A. Kennington IIId27410f2019-01-30 17:15:43 -08006#include <cstddef>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07007#include <cstring>
8#include <string>
9#include <string_view>
Ratan Gupta35297172018-11-28 18:40:16 +053010#include <xyz/openbmc_project/Common/error.hpp>
11
Gunnar Mills57d9c502018-09-14 14:42:34 -050012#include <gtest/gtest.h>
13
Ratan Gupta594123d2017-05-16 22:48:35 +053014namespace phosphor
15{
16namespace network
17{
18
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070019using namespace std::literals;
Ratan Gupta35297172018-11-28 18:40:16 +053020using InternalFailure =
21 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Ratan Gupta594123d2017-05-16 22:48:35 +053022class TestUtil : public testing::Test
23{
Gunnar Mills57d9c502018-09-14 14:42:34 -050024 public:
25 TestUtil()
26 {
27 // Empty
28 }
Ratan Gupta594123d2017-05-16 22:48:35 +053029};
30
William A. Kennington IIIa00b1c32019-02-01 18:57:17 -080031TEST_F(TestUtil, AddrFromBuf)
32{
33 std::string tooSmall(1, 'a');
34 std::string tooLarge(24, 'a');
35
36 struct in_addr ip1;
37 EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1));
38 std::string_view buf1(reinterpret_cast<char*>(&ip1), sizeof(ip1));
39 InAddrAny res1 = addrFromBuf(AF_INET, buf1);
40 EXPECT_EQ(0, memcmp(&ip1, &std::get<struct in_addr>(res1), sizeof(ip1)));
41 EXPECT_THROW(addrFromBuf(AF_INET, tooSmall), std::runtime_error);
42 EXPECT_THROW(addrFromBuf(AF_INET, tooLarge), std::runtime_error);
43 EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf1), std::runtime_error);
44
45 struct in6_addr ip2;
46 EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2));
47 std::string_view buf2(reinterpret_cast<char*>(&ip2), sizeof(ip2));
48 InAddrAny res2 = addrFromBuf(AF_INET6, buf2);
49 EXPECT_EQ(0, memcmp(&ip2, &std::get<struct in6_addr>(res2), sizeof(ip2)));
50 EXPECT_THROW(addrFromBuf(AF_INET6, tooSmall), std::runtime_error);
51 EXPECT_THROW(addrFromBuf(AF_INET6, tooLarge), std::runtime_error);
52 EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf2), std::runtime_error);
53}
54
William A. Kennington III5058f572019-01-30 17:18:14 -080055TEST_F(TestUtil, IpToString)
56{
57 struct in_addr ip1;
58 EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1));
59 EXPECT_EQ("192.168.10.1", toString(InAddrAny(ip1)));
60
61 struct in6_addr ip2;
62 EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2));
63 EXPECT_EQ("fdd8:b5ad:9d93:94ee::2:1", toString(InAddrAny(ip2)));
William A. Kennington III5058f572019-01-30 17:18:14 -080064}
65
Nagaraju Goruganti067ca2d2018-01-17 01:12:00 -060066TEST_F(TestUtil, IpValidation)
67{
68 std::string ipaddress = "0.0.0.0";
69 EXPECT_EQ(true, isValidIP(AF_INET, ipaddress));
70
71 ipaddress = "9.3.185.83";
72 EXPECT_EQ(true, isValidIP(AF_INET, ipaddress));
73
74 ipaddress = "9.3.185.a";
75 EXPECT_EQ(false, isValidIP(AF_INET, ipaddress));
76
77 ipaddress = "9.3.a.83";
78 EXPECT_EQ(false, isValidIP(AF_INET, ipaddress));
79
80 ipaddress = "x.x.x.x";
81 EXPECT_EQ(false, isValidIP(AF_INET, ipaddress));
82
83 ipaddress = "0:0:0:0:0:0:0:0";
84 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
85
86 ipaddress = "1:0:0:0:0:0:0:8";
87 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
88
89 ipaddress = "1::8";
90 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
91
92 ipaddress = "0:0:0:0:0:FFFF:204.152.189.116";
93 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
94
95 ipaddress = "::ffff:204.152.189.116";
96 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
97
98 ipaddress = "a:0:0:0:0:FFFF:204.152.189.116";
99 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
100
101 ipaddress = "1::8";
102 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
Nagaraju Goruganti067ca2d2018-01-17 01:12:00 -0600103}
104
105TEST_F(TestUtil, PrefixValidation)
106{
107 uint8_t prefixLength = 1;
108 EXPECT_EQ(true, isValidPrefix(AF_INET, prefixLength));
109
110 prefixLength = 32;
111 EXPECT_EQ(true, isValidPrefix(AF_INET, prefixLength));
112
113 prefixLength = 0;
114 EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength));
115
116 prefixLength = 33;
117 EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength));
118
119 prefixLength = 33;
120 EXPECT_EQ(true, isValidPrefix(AF_INET6, prefixLength));
121
122 prefixLength = 65;
123 EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength));
Nagaraju Goruganti067ca2d2018-01-17 01:12:00 -0600124}
125
Ratan Gupta594123d2017-05-16 22:48:35 +0530126TEST_F(TestUtil, ConvertV4MasktoPrefix)
127{
128 std::string mask = "255.255.255.0";
129 uint8_t prefix = toCidr(AF_INET, mask);
130 EXPECT_EQ(prefix, 24);
131
132 mask = "255.255.0.0";
133 prefix = toCidr(AF_INET, mask);
134 EXPECT_EQ(prefix, 16);
135
136 mask = "255.0.0.0";
137 prefix = toCidr(AF_INET, mask);
138 EXPECT_EQ(prefix, 8);
139
140 mask = "255.224.0.0";
141 prefix = toCidr(AF_INET, mask);
142 EXPECT_EQ(prefix, 11);
143
Gunnar Mills57d9c502018-09-14 14:42:34 -0500144 // Invalid Mask
Ratan Gupta594123d2017-05-16 22:48:35 +0530145 mask = "255.0.255.0";
146 prefix = toCidr(AF_INET, mask);
147 EXPECT_EQ(prefix, 0);
148}
149
150TEST_F(TestUtil, convertV6MasktoPrefix)
151{
152 std::string mask = "ffff:ffff::";
153 uint8_t prefix = toCidr(AF_INET6, mask);
154 EXPECT_EQ(prefix, 32);
155
156 mask = "ffff:ffff:ffff::";
157 prefix = toCidr(AF_INET6, mask);
158 EXPECT_EQ(prefix, 48);
159
160 mask = "ffff:ffff:fc00::";
161 prefix = toCidr(AF_INET6, mask);
162 EXPECT_EQ(prefix, 38);
163
Gunnar Mills57d9c502018-09-14 14:42:34 -0500164 // Invalid Mask
Ratan Gupta594123d2017-05-16 22:48:35 +0530165 mask = "ffff:0fff::";
166 prefix = toCidr(AF_INET6, mask);
167 EXPECT_EQ(prefix, 0);
168}
169
Ratan Gupta11cef802017-05-29 08:41:48 +0530170TEST_F(TestUtil, isLinkLocaladdress)
Ratan Gupta594123d2017-05-16 22:48:35 +0530171{
172 std::string ipaddress = "fe80:fec0::";
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500173 EXPECT_TRUE(isLinkLocalIP(ipaddress));
Ratan Gupta594123d2017-05-16 22:48:35 +0530174
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500175 ipaddress = "2000:fe80:789::";
176 EXPECT_FALSE(isLinkLocalIP(ipaddress));
Ratan Gupta594123d2017-05-16 22:48:35 +0530177
178 ipaddress = "2000:fe80::";
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500179 EXPECT_FALSE(isLinkLocalIP(ipaddress));
180
181 ipaddress = "169.254.3.3";
182 EXPECT_TRUE(isLinkLocalIP(ipaddress));
183
184 ipaddress = "3.169.254.3";
185 EXPECT_FALSE(isLinkLocalIP(ipaddress));
186
187 ipaddress = "3.3.169.254";
188 EXPECT_FALSE(isLinkLocalIP(ipaddress));
Ratan Gupta594123d2017-05-16 22:48:35 +0530189}
190
191TEST_F(TestUtil, convertPrefixToMask)
192{
193 std::string mask = toMask(AF_INET, 24);
194 EXPECT_EQ(mask, "255.255.255.0");
195
196 mask = toMask(AF_INET, 8);
197 EXPECT_EQ(mask, "255.0.0.0");
198
199 mask = toMask(AF_INET, 27);
200 EXPECT_EQ(mask, "255.255.255.224");
201}
202
Ratan Gupta11cef802017-05-29 08:41:48 +0530203TEST_F(TestUtil, getNetworkAddress)
204{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500205 std::string address = getNetworkID(AF_INET, "9.3.23.251", 24);
206 EXPECT_EQ("9.3.23.0", address);
Ratan Gupta11cef802017-05-29 08:41:48 +0530207
Gunnar Mills57d9c502018-09-14 14:42:34 -0500208 address = getNetworkID(AF_INET, "9.3.23.251", 25);
209 EXPECT_EQ("9.3.23.128", address);
Ratan Gupta11cef802017-05-29 08:41:48 +0530210
Gunnar Mills57d9c502018-09-14 14:42:34 -0500211 address = getNetworkID(AF_INET6, "2001:db8:abcd:dd12::0", 64);
212 EXPECT_EQ("2001:db8:abcd:dd12::", address);
Ratan Gupta11cef802017-05-29 08:41:48 +0530213
Ratan Gupta35297172018-11-28 18:40:16 +0530214 EXPECT_THROW(getNetworkID(AF_INET, "a.b.c.d", 25), InternalFailure);
Ratan Gupta11cef802017-05-29 08:41:48 +0530215
Ratan Gupta35297172018-11-28 18:40:16 +0530216 EXPECT_THROW(getNetworkID(AF_INET6, "2001:db8:gghh:dd12::0", 64),
217 InternalFailure);
Ratan Gupta11cef802017-05-29 08:41:48 +0530218
Gunnar Mills57d9c502018-09-14 14:42:34 -0500219 address = getNetworkID(AF_INET6, "fe80::201:6cff:fe80:228", 64);
220 EXPECT_EQ("fe80::", address);
Ratan Gupta11cef802017-05-29 08:41:48 +0530221}
222
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700223TEST_F(TestUtil, CopyFromTooSmall)
224{
225 constexpr auto expected = "abcde"sv;
226 struct
227 {
228 uint8_t data[10];
229 } data;
230 static_assert(sizeof(data) > expected.size());
231 EXPECT_THROW(copyFrom<decltype(data)>(expected), std::runtime_error);
232}
233
234TEST_F(TestUtil, CopyFromSome)
235{
236 constexpr auto expected = "abcde"sv;
237 struct
238 {
239 uint8_t data[2];
240 } data;
241 static_assert(sizeof(data) < expected.size());
242 data = copyFrom<decltype(data)>(expected);
243 EXPECT_EQ(0, memcmp(&data, expected.data(), sizeof(data)));
244}
245
246TEST_F(TestUtil, CopyFromAll)
247{
248 constexpr auto expected = "abcde"sv;
249 struct
250 {
251 uint8_t data[5];
252 } data;
253 static_assert(sizeof(data) == expected.size());
254 data = copyFrom<decltype(data)>(expected);
255 EXPECT_EQ(0, memcmp(&data, expected.data(), sizeof(data)));
256}
257
258TEST_F(TestUtil, ExtractSome)
259{
260 constexpr auto expected = "abcde"sv;
261 auto buf = expected;
262 struct
263 {
264 uint8_t data[2];
265 } data;
266 static_assert(sizeof(data) < expected.size());
267 data = extract<decltype(data)>(buf);
268 EXPECT_EQ(0, memcmp(&data, expected.data(), sizeof(data)));
269 EXPECT_EQ(3, buf.size());
270 EXPECT_EQ(expected.substr(2), buf);
271}
272
273TEST_F(TestUtil, ExtractAll)
274{
275 constexpr auto expected = "abcde"sv;
276 auto buf = expected;
277 struct
278 {
279 uint8_t data[5];
280 } data;
281 static_assert(sizeof(data) == expected.size());
282 data = extract<decltype(data)>(buf);
283 EXPECT_EQ(0, memcmp(&data, expected.data(), sizeof(data)));
284 EXPECT_EQ(0, buf.size());
285}
286
287TEST_F(TestUtil, Equal)
288{
289 struct
290 {
291 int i;
292 } a, b{};
293 a.i = 4;
294 b.i = 4;
295
296 EXPECT_TRUE(equal(a, b));
297}
298
299TEST_F(TestUtil, NotEqual)
300{
301 struct
302 {
303 int i;
304 } a, b{};
305 a.i = 2;
306 b.i = 4;
307
308 EXPECT_FALSE(equal(a, b));
309}
310
William A. Kennington III1137a972019-04-20 20:49:58 -0700311namespace mac_address
312{
313
314TEST(MacFromString, Bad)
315{
316 EXPECT_THROW(fromString("0x:00:00:00:00:00"), std::runtime_error);
317 EXPECT_THROW(fromString("00:00:00:00:00"), std::runtime_error);
318 EXPECT_THROW(fromString(""), std::runtime_error);
319}
320
321TEST(MacFromString, Valid)
322{
323 EXPECT_TRUE(equal(ether_addr{}, fromString("00:00:00:00:00:00")));
324 EXPECT_TRUE(equal(ether_addr{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa},
325 fromString("FF:EE:DD:cc:bb:aa")));
326 EXPECT_TRUE(equal(ether_addr{0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
327 fromString("0:1:2:3:4:5")));
328}
329
330TEST(MacToString, Valid)
331{
332 EXPECT_EQ("11:22:33:44:55:66",
333 toString({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}));
334}
335
336TEST(MacIsEmpty, True)
337{
338 EXPECT_TRUE(isEmpty({}));
339}
340
341TEST(MacIsEmpty, False)
342{
343 EXPECT_FALSE(isEmpty(fromString("01:00:00:00:00:00")));
344 EXPECT_FALSE(isEmpty(fromString("00:00:00:10:00:00")));
345 EXPECT_FALSE(isEmpty(fromString("00:00:00:00:00:01")));
346}
347
348TEST(MacIsMulticast, True)
349{
350 EXPECT_TRUE(isMulticast(fromString("ff:ff:ff:ff:ff:ff")));
351 EXPECT_TRUE(isMulticast(fromString("01:00:00:00:00:00")));
352}
353
354TEST(MacIsMulticast, False)
355{
356 EXPECT_FALSE(isMulticast(fromString("00:11:22:33:44:55")));
357 EXPECT_FALSE(isMulticast(fromString("FE:11:22:33:44:55")));
358}
359
360TEST(MacIsUnicast, True)
361{
362 EXPECT_TRUE(isUnicast(fromString("00:11:22:33:44:55")));
363 EXPECT_TRUE(isUnicast(fromString("FE:11:22:33:44:55")));
364}
365
366TEST(MacIsUnicast, False)
367{
368 EXPECT_FALSE(isUnicast(fromString("00:00:00:00:00:00")));
369 EXPECT_FALSE(isUnicast(fromString("01:00:00:00:00:00")));
370 EXPECT_FALSE(isUnicast(fromString("ff:ff:ff:ff:ff:ff")));
371}
372
373TEST(MacIsLocalAdmin, True)
374{
375 EXPECT_TRUE(isLocalAdmin(fromString("02:11:22:33:44:55")));
376 EXPECT_TRUE(isLocalAdmin(fromString("FE:11:22:33:44:55")));
377}
378
379TEST(MacIsLocalAdmin, False)
380{
381 EXPECT_FALSE(isLocalAdmin(fromString("00:00:00:00:00:00")));
382 EXPECT_FALSE(isLocalAdmin(fromString("01:00:00:00:00:00")));
383 EXPECT_FALSE(isLocalAdmin(fromString("fd:ff:ff:ff:ff:ff")));
384}
385
386} // namespace mac_address
Gunnar Mills57d9c502018-09-14 14:42:34 -0500387} // namespace network
388} // namespace phosphor